From de99f0aaeb63a8813ad3de64fd3d77b64e02ef38 Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Fri, 20 Jan 2006 14:21:28 +0000 Subject: [PATCH] More function wrapping tests. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5568 --- memcheck/tests/Makefile.am | 18 +++++- memcheck/tests/wrap7.c | 30 ++++++++++ memcheck/tests/wrap7.stderr.exp | 0 memcheck/tests/wrap7.stdout.exp | 4 ++ memcheck/tests/wrap7.vgtest | 2 + memcheck/tests/wrap7so.c | 10 ++++ memcheck/tests/wrap8.c | 102 ++++++++++++++++++++++++++++++++ memcheck/tests/wrap8.stderr.exp | 17 ++++++ memcheck/tests/wrap8.stdout.exp | 17 ++++++ memcheck/tests/wrap8.vgtest | 2 + 10 files changed, 201 insertions(+), 1 deletion(-) create mode 100644 memcheck/tests/wrap7.c create mode 100644 memcheck/tests/wrap7.stderr.exp create mode 100644 memcheck/tests/wrap7.stdout.exp create mode 100644 memcheck/tests/wrap7.vgtest create mode 100644 memcheck/tests/wrap7so.c create mode 100644 memcheck/tests/wrap8.c create mode 100644 memcheck/tests/wrap8.stderr.exp create mode 100644 memcheck/tests/wrap8.stdout.exp create mode 100644 memcheck/tests/wrap8.vgtest diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am index 3c178e8c1..ee9f7de92 100644 --- a/memcheck/tests/Makefile.am +++ b/memcheck/tests/Makefile.am @@ -114,6 +114,8 @@ EXTRA_DIST = $(noinst_SCRIPTS) \ wrap4.vgtest wrap4.stdout.exp wrap4.stderr.exp \ wrap5.vgtest wrap5.stdout.exp wrap5.stderr.exp \ wrap6.vgtest wrap6.stdout.exp wrap6.stderr.exp \ + wrap7.vgtest wrap7.stdout.exp wrap7.stderr.exp \ + wrap8.vgtest wrap8.stdout.exp wrap8.stderr.exp \ writev.stderr.exp writev.stderr.exp2 writev.stderr.exp3 writev.vgtest \ xml1.stderr.exp xml1.stderr.exp2 xml1.stderr.exp3 \ xml1.stderr.exp64 xml1.stderr.exp64_2 xml1.stdout.exp \ @@ -147,7 +149,7 @@ check_PROGRAMS = \ trivialleak \ mismatches new_override metadata \ xml1 \ - wrap1 wrap2 wrap3 wrap4 wrap5 wrap6 \ + wrap1 wrap2 wrap3 wrap4 wrap5 wrap6 wrap7 wrap7so.so wrap8 \ writev zeropage @@ -162,6 +164,7 @@ memcmptest_CFLAGS = $(AM_FLAG_M3264_PRI) $(AM_CFLAGS) -fno-builtin-memcmp oset_test_CFLAGS = $(AM_FLAG_M3264_PRI) \ -DVGA_$(VG_ARCH)=1 -DVGO_$(VG_OS)=1 \ -DVGP_$(VG_ARCH)_$(VG_OS)=1 + # Don't allow GCC to inline memcpy(), because then we can't intercept it overlap_CFLAGS = $(AM_CFLAGS) -fno-builtin-memcpy stack_switch_LDADD = -lpthread @@ -175,6 +178,19 @@ mismatches_SOURCES = mismatches.cpp new_nothrow_SOURCES = new_nothrow.cpp new_override_SOURCES = new_override.cpp +# Build shared object for wrap7 +wrap7_SOURCES = wrap7.c +wrap7_DEPENDENCIES = wrap7so.so +wrap7_LDFLAGS = $(AM_FLAG_M3264_PRI) \ + -Wl,-rpath,$(top_builddir)/memcheck/tests +wrap7_LDADD = wrap7so.so +wrap7so_so_SOURCES = wrap7so.c +wrap7so_so_LDADD = +wrap7so_so_DEPENDENCIES = +wrap7so_so_LDFLAGS = -fpic $(AM_FLAG_M3264_PRI) \ + -Wl,-soname -Wl,wrap7so.so -shared +wrap7so_so_CFLAGS = -fpic $(AM_FLAG_M3264_PRI) + # Valgrind unit self-tests #hello_LDFLAGS = -Wl,-defsym,valt_load_address=0x50000000 \ # -Wl,-T,$(top_builddir)/valt_load_address.lds diff --git a/memcheck/tests/wrap7.c b/memcheck/tests/wrap7.c new file mode 100644 index 000000000..5d76f3f19 --- /dev/null +++ b/memcheck/tests/wrap7.c @@ -0,0 +1,30 @@ + +#include +#include "valgrind.h" + +/* The simplest possible wrapping test: just call a wrapped function + and check we run the wrapper instead. Except: the wrapped + function is in a different shared object. This causes some + additional complications on ppc64-linux, hence another test. */ + +extern void actual ( void ); + +/* The wrapper. The function being wrapped is in a .so with soname + "wrap7so.so". */ +void I_WRAP_SONAME_FNNAME_ZU(wrap7soZdso,actual) ( void ) +{ + OrigFn orig; + VALGRIND_GET_ORIG_FN(orig); + printf("wrapper-pre\n"); + CALL_FN_v_v(orig); + printf("wrapper-post\n"); +} + +/* --------------- */ + +int main ( void ) +{ + printf("starting\n"); + actual(); + return 0; +} diff --git a/memcheck/tests/wrap7.stderr.exp b/memcheck/tests/wrap7.stderr.exp new file mode 100644 index 000000000..e69de29bb diff --git a/memcheck/tests/wrap7.stdout.exp b/memcheck/tests/wrap7.stdout.exp new file mode 100644 index 000000000..802521d9b --- /dev/null +++ b/memcheck/tests/wrap7.stdout.exp @@ -0,0 +1,4 @@ +starting +wrapper-pre +in actual-so +wrapper-post diff --git a/memcheck/tests/wrap7.vgtest b/memcheck/tests/wrap7.vgtest new file mode 100644 index 000000000..4bb558d61 --- /dev/null +++ b/memcheck/tests/wrap7.vgtest @@ -0,0 +1,2 @@ +prog: wrap7 +vgopts: -q diff --git a/memcheck/tests/wrap7so.c b/memcheck/tests/wrap7so.c new file mode 100644 index 000000000..35f3855ce --- /dev/null +++ b/memcheck/tests/wrap7so.c @@ -0,0 +1,10 @@ + +#include +#include +/* The "original" function */ + +void actual ( void ) +{ + printf("in actual-so\n"); +} + diff --git a/memcheck/tests/wrap8.c b/memcheck/tests/wrap8.c new file mode 100644 index 000000000..39a9c3ca8 --- /dev/null +++ b/memcheck/tests/wrap8.c @@ -0,0 +1,102 @@ + +#include +#include +#include "valgrind.h" + +/* This is the same as wrap5.c, except that the recursion depth is 16. + This is intended to check that on ppc64-linux, which uses a + 16-entry per-thread stack, the resulting stack overflow is caught. + (Undetected overflows in redirection stacks are very bad news; they + cause guest code to fail in all sorts of strange ways.) + + Hence this test has two expected outcomes: + - on ppc64-linux, a stack overflow is caught, and V aborts. + - on everything else, it runs successfully to completion. +*/ + +typedef + struct _Lard { + struct _Lard* next; + char stuff[999]; + } + Lard; + +Lard* lard = NULL; +static int ctr = 0; + +void addMoreLard ( void ) +{ + Lard* p; + ctr++; + if ((ctr % 3) == 1) { + p = malloc(sizeof(Lard)); + p->next = lard; + lard = p; + } +} + + +static int fact1 ( int n ); +static int fact2 ( int n ); + +/* This is needed to stop gcc4 turning 'fact' into a loop */ +__attribute__((noinline)) +int mul ( int x, int y ) { return x * y; } + +int fact1 ( int n ) +{ + addMoreLard(); + if (n == 0) return 1; else return mul(n, fact2(n-1)); +} +int fact2 ( int n ) +{ + addMoreLard(); + if (n == 0) return 1; else return mul(n, fact1(n-1)); +} + + +int I_WRAP_SONAME_FNNAME_ZU(NONE,fact1) ( int n ) +{ + int r; + OrigFn fn; + VALGRIND_GET_ORIG_FN(fn); + printf("in wrapper1-pre: fact(%d)\n", n); fflush(stdout); + addMoreLard(); + CALL_FN_W_W(r, fn, n); + addMoreLard(); + printf("in wrapper1-post: fact(%d) = %d\n", n, r); fflush(stdout); + if (n >= 3) r += fact2(2); + return r; +} + +int I_WRAP_SONAME_FNNAME_ZU(NONE,fact2) ( int n ) +{ + int r; + OrigFn fn; + VALGRIND_GET_ORIG_FN(fn); + printf("in wrapper2-pre: fact(%d)\n", n); fflush(stdout); + addMoreLard(); + CALL_FN_W_W(r, fn, n); + addMoreLard(); + printf("in wrapper2-post: fact(%d) = %d\n", n, r); fflush(stdout); + return r; +} + +/* --------------- */ + +int main ( void ) +{ + int r, n = 15; /* 14 succeeds on ppc64-linux, >= 15 fails */ + Lard *p, *p_next; + printf("computing fact1(%d)\n", n); fflush(stdout); + r = fact1(n); + printf("fact1(%d) = %d\n", n, r); fflush(stdout); + + printf("allocated %d Lards\n", ctr); fflush(stdout); + for (p = lard; p; p = p_next) { + p_next = p->next; + free(p); + } + + return 0; +} diff --git a/memcheck/tests/wrap8.stderr.exp b/memcheck/tests/wrap8.stderr.exp new file mode 100644 index 000000000..8376e95d2 --- /dev/null +++ b/memcheck/tests/wrap8.stderr.exp @@ -0,0 +1,17 @@ +Emulation fatal error -- Valgrind cannot continue: + PPC64 function redirection stack overflow + at 0x........: ??? + by 0x........: fact2 (wrap8.c:78) + by 0x........: ... + by 0x........: fact1 (wrap8.c:65) + by 0x........: ... + by 0x........: fact2 (wrap8.c:79) + by 0x........: ... + by 0x........: fact1 (wrap8.c:65) + by 0x........: ... + by 0x........: fact2 (wrap8.c:79) + by 0x........: ... + by 0x........: fact1 (wrap8.c:65) + +Valgrind has to exit now. Sorry. + diff --git a/memcheck/tests/wrap8.stdout.exp b/memcheck/tests/wrap8.stdout.exp new file mode 100644 index 000000000..e5c677b36 --- /dev/null +++ b/memcheck/tests/wrap8.stdout.exp @@ -0,0 +1,17 @@ +computing fact1(15) +in wrapper1-pre: fact(15) +in wrapper2-pre: fact(14) +in wrapper1-pre: fact(13) +in wrapper2-pre: fact(12) +in wrapper1-pre: fact(11) +in wrapper2-pre: fact(10) +in wrapper1-pre: fact(9) +in wrapper2-pre: fact(8) +in wrapper1-pre: fact(7) +in wrapper2-pre: fact(6) +in wrapper1-pre: fact(5) +in wrapper2-pre: fact(4) +in wrapper1-pre: fact(3) +in wrapper2-pre: fact(2) +in wrapper1-pre: fact(1) +in wrapper2-pre: fact(0) diff --git a/memcheck/tests/wrap8.vgtest b/memcheck/tests/wrap8.vgtest new file mode 100644 index 000000000..b9680ac80 --- /dev/null +++ b/memcheck/tests/wrap8.vgtest @@ -0,0 +1,2 @@ +prog: wrap8 +vgopts: -q