]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Add a not very good test pertaining to the preening of global Invars
authorJulian Seward <jseward@acm.org>
Mon, 20 Oct 2008 11:14:50 +0000 (11:14 +0000)
committerJulian Seward <jseward@acm.org>
Mon, 20 Oct 2008 11:14:50 +0000 (11:14 +0000)
upon unmapping of a shared object, in sg_main.c.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@8681

exp-ptrcheck/tests/Makefile.am
exp-ptrcheck/tests/preen_invars.c [new file with mode: 0644]
exp-ptrcheck/tests/preen_invars.stderr.exp-glibc28-amd64 [new file with mode: 0644]
exp-ptrcheck/tests/preen_invars.stdout.exp [new file with mode: 0644]
exp-ptrcheck/tests/preen_invars.vgtest [new file with mode: 0644]
exp-ptrcheck/tests/preen_invars_so.c [new file with mode: 0644]

index 9b6f46ffef67bf20b31b2ac26f790c3ce4cddb6d..38512ab77b42c9ed4e60291e7a41964ff9a9400a 100644 (file)
@@ -54,6 +54,8 @@ EXTRA_DIST = $(noinst_SCRIPTS) \
        partial_good.vgtest \
        partial_good.stderr.exp-glibc25-x86 \
        partial_good.stderr.exp-glibc25-amd64 \
+       preen_invars.vgtest preen_invars.stdout.exp \
+       preen_invars.stderr.exp-glibc28-amd64 \
        pth_create.vgtest pth_create.stderr.exp \
        pth_specific.vgtest pth_specific.stderr.exp \
        realloc.vgtest \
@@ -78,7 +80,9 @@ check_PROGRAMS = \
        add and arith bad_percentify base ccc cmp fp \
        globalerr hackedbz2 \
        hp_bounds hp_dangle idiv imul \
-       justify mm not neg or partial pth_create pth_specific realloc \
+       justify mm not neg or partial \
+       preen_invars preen_invars_so.so \
+       pth_create pth_specific realloc \
        stackerr \
        strcpy strlen sub supp syscall tricky unaligned xor zero
 
@@ -130,3 +134,37 @@ zero_SOURCES               = zero.c
 
 # C++ ones
 ccc_SOURCES            = ccc.cpp
+
+# Build shared object for preen_invars
+preen_invars_SOURCES           = preen_invars.c
+preen_invars_DEPENDENCIES      = preen_invars_so.so
+if VGP_PPC64_AIX5 
+ preen_invars_LDADD            = -ldl
+ preen_invars_LDFLAGS          = $(AM_FLAG_M3264_PRI)
+else
+if VGP_PPC32_AIX5
+ preen_invars_LDADD            = -ldl
+ preen_invars_LDFLAGS          = $(AM_FLAG_M3264_PRI) -Wl,-G -Wl,-bnogc
+else
+ preen_invars_LDADD            = -ldl
+ preen_invars_LDFLAGS          = $(AM_FLAG_M3264_PRI) \
+                               -Wl,-rpath,$(top_builddir)/memcheck/tests
+endif
+endif
+
+preen_invars_so_so_SOURCES      = preen_invars_so.c
+preen_invars_so_so_LDADD        = 
+preen_invars_so_so_DEPENDENCIES = 
+preen_invars_so_so_CFLAGS       = -fpic $(AM_FLAG_M3264_PRI) -g
+if VGP_PPC64_AIX5
+ preen_invars_so_so_LDFLAGS     = -fpic $(AM_FLAG_M3264_PRI) -shared
+else
+if VGP_PPC32_AIX5
+ preen_invars_so_so_LDFLAGS     = -fpic $(AM_FLAG_M3264_PRI) -shared \
+                                       -Wl,-G -Wl,-bnogc
+else
+ preen_invars_so_so_LDFLAGS     = -fpic $(AM_FLAG_M3264_PRI) -shared \
+                                       -Wl,-soname -Wl,preen_invars_so.so
+endif
+endif
+
diff --git a/exp-ptrcheck/tests/preen_invars.c b/exp-ptrcheck/tests/preen_invars.c
new file mode 100644 (file)
index 0000000..cef91be
--- /dev/null
@@ -0,0 +1,52 @@
+
+#include <stdio.h>
+#include <assert.h>
+#include <dlfcn.h>
+
+/* see comments in preen_invar_so.c for explanation of this */
+
+
+int main ( void )
+{
+  int i, r, sum = 0;
+  char* im_a_global_array;
+  void* hdl = dlopen("./preen_invars_so.so", RTLD_NOW);
+  assert(hdl);
+  im_a_global_array = dlsym(hdl, "im_a_global_array");
+  assert(im_a_global_array);
+  /* printf("%p %p\n", im_a_global_array, me_too_me_too); */
+
+  /* poke around in the global array, so as to cause exp-ptrcheck
+     to generate an Inv_Global invar for it. */
+  for (i = 10/*ERROR*/; i >= 0; i--) {
+     sum += im_a_global_array[i];
+  }
+  /* iterating 10 .. 0 causes an Unknown->Global transition at i = 9.
+     We do it this way in order that at the end of a loop, there is a
+     Global invar in place for the memory read in the loop, so that
+     the subsequent dlclose (hence munmap) causes it to get preened.
+
+     Unfortunately there's nothing to show that the preen was
+     successful or happened at all.  The only way to see is from the
+     -v output:
+
+     --686--  sg_:  251 Invars preened, of which 1 changed
+
+     It's the "1 changed" bit which is significant.
+  */
+
+  /* let's hope gcc is not clever enough to optimise this away, since
+     if it does, then it will also nuke the preceding loop, and
+     thereby render this test program useless. */
+
+  if (sum & 1) printf("%s bar %d\n", "foo", sum & 1); else
+               printf("foo %s %d\n", "bar", 1 - (sum & 1));
+
+  /* Now close (== unmap) the array, so that exp-ptrcheck has to check
+     its collection of Inv_Global invars, and remove this one from
+     it. */
+  r = dlclose(hdl);
+  assert(r == 0);
+
+  return 0;
+}
diff --git a/exp-ptrcheck/tests/preen_invars.stderr.exp-glibc28-amd64 b/exp-ptrcheck/tests/preen_invars.stderr.exp-glibc28-amd64
new file mode 100644 (file)
index 0000000..8d07c63
--- /dev/null
@@ -0,0 +1,8 @@
+
+Invalid read of size 1
+   at 0x........: main (preen_invars.c:22)
+ Address 0x........ expected vs actual:
+ Expected: unknown
+ Actual:   global array "im_a_global_arr" in object with soname "preen_invars_so"
+
+ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
diff --git a/exp-ptrcheck/tests/preen_invars.stdout.exp b/exp-ptrcheck/tests/preen_invars.stdout.exp
new file mode 100644 (file)
index 0000000..b3162be
--- /dev/null
@@ -0,0 +1 @@
+foo bar 1
diff --git a/exp-ptrcheck/tests/preen_invars.vgtest b/exp-ptrcheck/tests/preen_invars.vgtest
new file mode 100644 (file)
index 0000000..c654c18
--- /dev/null
@@ -0,0 +1 @@
+prog: preen_invars
diff --git a/exp-ptrcheck/tests/preen_invars_so.c b/exp-ptrcheck/tests/preen_invars_so.c
new file mode 100644 (file)
index 0000000..0e59d9c
--- /dev/null
@@ -0,0 +1,12 @@
+
+/* This file contains a global array.  It is compiled into a .so,
+   which is dlopened by preen_invar.c.  That then accesses the global
+   array, hence generating Inv_Global invariants in sg_main.c.
+
+   preen_invar.c then dlcloses this object, causing it to get
+   unmapped; and we then need to be sure that the Inv_Global is
+   removed by preen_Invars (or, at least, that the system doesn't
+   crash..). */
+
+char im_a_global_array[10];
+