Added a unit self-test -- a test program that incorporates a small part of

Valgrind itself (the files ume.c, ume_entry.c and jmp_with_stack.c).  Thus,
we are using Memcheck to check these files in a unit test setting.

I hope to do unit self-testing for many more parts of Valgrind, eventually all
the bits that can be pulled out into any kind of sensible stand-alone form.
Doing so achieves two things:

 a) it introduces unit testing into our framework (a serious shortcoming at the
    moment)
 b) it lets us use Valgrind (esp. Memcheck) on itself, to some extent

This should help reliability.  This first unit self-test isn't very exhaustive,
but it's a start.

Note that this involves something like bootstrapping, in that we are checking
parts of a Valgrind build with itself.  I don't think this will be a problem,
since we (at least, I do) tend to only run the regtests when we think the
Valgrind build is ok.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2760
This commit is contained in:
Nicholas Nethercote 2004-10-14 08:38:06 +00:00
parent 5aa943f129
commit 5435f2c2ec
6 changed files with 104 additions and 2 deletions

View File

@ -21,6 +21,7 @@ filter_stderr
fpeflags
fprw
fwrite
hello
inits
inline
malloc1
@ -49,6 +50,7 @@ supp2
suppfree
trivialleak
tronical
vgtest_ume
weirdioctl
*.stdout.diff
*.stderr.diff

View File

@ -75,6 +75,7 @@ EXTRA_DIST = $(noinst_SCRIPTS) \
metadata.stderr.exp metadata.stdout.exp metadata.vgtest \
threadederrno.stderr.exp threadederrno.stdout.exp \
threadederrno.vgtest \
vgtest_ume.stderr.exp vgtest_ume.vgtest \
writev.stderr.exp writev.vgtest \
zeropage.stderr.exp zeropage.stderr.exp2 zeropage.vgtest
@ -83,14 +84,17 @@ check_PROGRAMS = \
badloop badrw brk brk2 buflen_check \
clientperm custom_alloc \
doublefree error_counts errs1 exitprog execve execve2 \
fpeflags fprw fwrite inits inline \
fpeflags fprw fwrite hello inits inline \
malloc1 malloc2 malloc3 manuel1 manuel2 manuel3 \
memalign_test memalign2 memcmptest mempool mmaptest \
nanoleak new_nothrow \
null_socket overlap pushfpopf \
realloc1 realloc2 realloc3 sigaltstack signal2 supp1 supp2 suppfree \
trivialleak tronical weirdioctl \
mismatches new_override metadata threadederrno writev zeropage
mismatches new_override metadata threadederrno \
vgtest_ume \
writev zeropage
AM_CPPFLAGS = -I$(top_srcdir)/include
AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -g
@ -148,6 +152,7 @@ weirdioctl_SOURCES = weirdioctl.c
metadata_SOURCES = metadata.c
threadederrno_SOURCES = threadederrno.c
threadederrno_LDADD = -lpthread
vgtest_ume_SOURCES = vgtest_ume.c
writev_SOURCES = writev.c
zeropage_SOURCES = zeropage.c
@ -156,5 +161,13 @@ mismatches_SOURCES = mismatches.cpp
new_nothrow_SOURCES = new_nothrow.cpp
new_override_SOURCES = new_override.cpp
# Valgrind unit self-tests
hello_SOURCES = hello.c
hello_LDFLAGS = -Wl,-defsym,kickstart_base=0x50000000 \
-Wl,-T,../../coregrind/${VG_ARCH}/stage2.lds
vgtest_ume_LDADD = ../../coregrind/ume.o \
../../coregrind/ume_entry.o \
../../coregrind/jmp_with_stack.o
# must be built with these flags -- bug only occurred with them
fpeflags.o: CFLAGS += -march=i686

9
memcheck/tests/hello.c Normal file
View File

@ -0,0 +1,9 @@
#include <stdio.h>
int main(void)
{
fprintf(stderr, "Hello, world!\n");
return 0;
}

View File

@ -0,0 +1,75 @@
#define ELFSZ 32
// This file is a unit self-test for ume.c, ume_entry.c, jmp_with_stack.c
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <elf.h>
#include "../../coregrind/ume.h"
#define STKSZ (64*1024)
static void push_auxv(unsigned char **espp, int type, void *val)
{
struct ume_auxv *auxp = (struct ume_auxv *)*espp;
auxp--;
auxp->a_type = type;
auxp->u.a_ptr = val;
*espp = (unsigned char *)auxp;
}
static void push(unsigned char **espp, void *v)
{
void **vp = *(void ***)espp;
*--vp = v;
*espp = (unsigned char *)vp;
}
int main(void)
{
struct exeinfo info;
int err;
unsigned char* newstack;
unsigned char *esp;
info.argv = NULL;
info.exe_base = 0x50000000;
info.exe_end = 0x50ffffff;
info.map_base = 0x51000000;
err = do_exec("hello", &info);
assert(0 == err);
// printf("info.exe_base=%p exe_end=%p\n",
// (void*)info.exe_base, (void*)info.exe_end);
newstack = malloc(STKSZ);
assert(0 != newstack);
esp = newstack+STKSZ;
/*
Set the new executable's stack up like the kernel would after
exec.
These are being pushed onto the stack, towards decreasing
addresses.
*/
push_auxv(&esp, AT_NULL, 0); // auxv terminator
push_auxv(&esp, AT_ENTRY, (void *)info.entry); // entrypoint of the main executable */
push_auxv(&esp, AT_BASE, (void *)info.interp_base); // base address of ld-linux.so
push_auxv(&esp, AT_PHDR, (void *)info.phdr); // where the ELF PHDRs are mapped
push_auxv(&esp, AT_PHNUM, (void*)info.phnum); // and how many of them
push(&esp, 0); /* no env */
push(&esp, 0); /* no argv */
push(&esp, 0); /* argc=0 */
// fprintf(stderr, "ume_go: %p %p\n", (void*)info.init_eip, (void*)esp);
jmp_with_stack(info.init_eip, (addr_t)esp);
return 0;
}

View File

@ -0,0 +1 @@
Hello, world!

View File

@ -0,0 +1,2 @@
prog: vgtest_ume
vgopts: -q