This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH,boehm-gc,PR42811] Add followup testcase to


    Hello again,

  One issue that was exposed(*) when I fixed GCC PR42811(**) was that when you
have a shared library that proxies access to the GC, as indeed libjava
effectively does, and in particular when is is from within that shared library
that the GC is initialised, it may end up being that it is only the library's
data and bss sections that get registered to be scanned for static roots, and
that the GC may lose sight of pointers to GC-allocated memory if the library
returns them to the main application, which hangs onto a copy of the pointer
in its own data or bss space while the library does not.

  This doesn't in fact arise on Linux platforms, where there is dynamic
registration of loaded modules, but it used to happen on Windows before I
fixed it.  I said I'd look at following up with a testcase, and here it is.

  The attached testcase simulates the interaction between shared libjava
containing statically-linked GC and an application as described above.  On
i686-pc-cygwin, it reliably failed prior to the patch for PR42811, and
reliably passes since then; on i686-pc-linux-gnu, it passes in either case anyway.

  While I was at it, I noticed that we've disabled all but one of the boehm-gc
tests in our copy of the tree.  Being as I was in there anyway, I decided to
see what happened if I re-enabled a couple of the others; they all passed on
both cygwin and linux targets, so I thought, "Why not?"(***), and left them there.

boehm-gc/ChangeLog:

	* tests/staticrootstest.c: New test source file.
	* boehm-gc/tests/staticrootslib.c: New test library source file.
	* Makefile.am (test_ldadd): New variable.
	(gctest_LDADD): Use it.
	(TESTS): Add leaktest, middletest and staticrootstest.
	(check_PROGRAMS): Likewise.
	(leaktest_SOURCES): New libtool variable definition.
	(leaktest_LDADD): Likewise.
	(leaktest_LDFLAGS): Likewise.
	(leaktest_LINK): Likewise.
	(middletest_SOURCES): Likewise.
	(middletest_LDADD): Likewise.
	(middletest_LDFLAGS): Likewise.
	(middletest_LINK): Likewise.
	(staticrootstest_SOURCES): Likewise.
	(staticrootstest_LDADD): Likewise.
	(staticrootstest_LDFLAGS): Likewise.
	(staticrootstest_LINK): Likewise.
	(check_LTLIBRARIES): Likewise.
	(libstaticrootslib_la_SOURCES): Likewise.
	(libstaticrootslib_la_LIBADD): Likewise.
	(libstaticrootslib_la_LDFLAGS): Likewise.
	(libstaticrootslib_la_DEPENDENCIES): Likewise.

  The new test has already been committed upstream.  I just re-verified that
all the tests pass on i686-pc-cygwin from my latest LTO build from earlier
last night.  OK for HEAD?

    cheers,
      DaveK
-- 
(*)   - http://gcc.gnu.org/ml/java/2010-02/threads.html#00004
(**)  - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42811
(***) - That's a good reason for almost anything - a bit used perhaps, but
still quite serviceable.

Index: boehm-gc/tests/staticrootstest.c
===================================================================
--- boehm-gc/tests/staticrootstest.c	(revision 0)
+++ boehm-gc/tests/staticrootstest.c	(revision 0)
@@ -0,0 +1,46 @@
+#include <stdio.h>
+
+#ifndef GC_DEBUG
+# define GC_DEBUG
+#endif
+
+#include "gc.h"
+#include "gc_backptr.h"
+
+struct treenode {
+    struct treenode *x;
+    struct treenode *y;
+} * root[10];
+
+static char *staticroot = 0;
+
+extern struct treenode * libsrl_mktree(int i);
+extern void * libsrl_init(void);
+extern void * libsrl_collect (void);
+
+int main(void)
+{
+  int i;
+  staticroot = libsrl_init();
+  for (i = 0; i < sizeof(struct treenode); ++i) {
+    staticroot[i] = 0x42;
+  }
+  libsrl_collect();
+  for (i = 0; i < 10; ++i) {
+    root[i] = libsrl_mktree(12);
+    libsrl_collect();
+  }
+  for (i = 0; i < sizeof(struct treenode); ++i) {
+    if (staticroot[i] != 0x42)
+      return -1;
+  }
+  for (i = 0; i < 10; ++i) {
+    root[i] = libsrl_mktree(12);
+    libsrl_collect();
+  }
+  for (i = 0; i < sizeof(struct treenode); ++i) {
+    if (staticroot[i] != 0x42)
+      return -1;
+  }
+  return 0;
+}
Index: boehm-gc/tests/staticrootslib.c
===================================================================
--- boehm-gc/tests/staticrootslib.c	(revision 0)
+++ boehm-gc/tests/staticrootslib.c	(revision 0)
@@ -0,0 +1,33 @@
+#include <stdio.h>
+
+#ifndef GC_DEBUG
+# define GC_DEBUG
+#endif
+
+#include "gc.h"
+
+struct treenode {
+    struct treenode *x;
+    struct treenode *y;
+} * root[10];
+
+struct treenode * libsrl_mktree(int i)
+{
+  struct treenode * r = GC_MALLOC(sizeof(struct treenode));
+  if (0 == i) return 0;
+  if (1 == i) r = GC_MALLOC_ATOMIC(sizeof(struct treenode));
+  r -> x = libsrl_mktree(i-1);
+  r -> y = libsrl_mktree(i-1);
+  return r;
+}
+
+void * libsrl_init(void)
+{
+  GC_INIT();
+  return GC_MALLOC(sizeof(struct treenode));
+}
+
+void * libsrl_collect (void)
+{
+  GC_gcollect();
+}
Index: boehm-gc/Makefile.am
===================================================================
--- boehm-gc/Makefile.am	(revision 158764)
+++ boehm-gc/Makefile.am	(working copy)
@@ -48,14 +48,43 @@ libgcjgc_convenience_la_DEPENDENCIES = @addobjs@
 AM_CXXFLAGS = @GC_CFLAGS@
 AM_CFLAGS = @GC_CFLAGS@
 
+test_ldadd = libgcjgc.la $(THREADLIBS) $(UNWINDLIBS) $(EXTRA_TEST_LIBS)
+
 check_PROGRAMS = gctest
 gctest_SOURCES = tests/test.c
-gctest_LDADD = libgcjgc.la $(THREADLIBS) $(UNWINDLIBS) $(EXTRA_TEST_LIBS)
+gctest_LDADD = $(test_ldadd)
 gctest_LDFLAGS = -shared-libgcc
 gctest_LINK = $(LINK) $(gctest_LDFLAGS)
 TESTS_ENVIRONMENT = LD_LIBRARY_PATH=../../$(MULTIBUILDTOP)gcc
 TESTS = gctest
 
+TESTS += leaktest$(EXEEXT)
+check_PROGRAMS += leaktest
+leaktest_SOURCES = tests/leak_test.c
+leaktest_LDADD = $(test_ldadd)
+leaktest_LDFLAGS = -shared-libgcc
+leaktest_LINK = $(LINK) $(leaktest_LDFLAGS)
+
+TESTS += middletest$(EXEEXT)
+check_PROGRAMS += middletest
+middletest_SOURCES = tests/middle.c
+middletest_LDADD = $(test_ldadd)
+middletest_LDFLAGS = -shared-libgcc
+middletest_LINK = $(LINK) $(middletest_LDFLAGS)
+
+TESTS += staticrootstest$(EXEEXT)
+check_PROGRAMS += staticrootstest
+staticrootstest_SOURCES = tests/staticrootstest.c
+staticrootstest_LDADD = $(test_ldadd) libstaticrootslib.la
+staticrootstest_LDFLAGS = -shared-libgcc
+staticrootstest_LINK = $(LINK) $(staticrootstest_LDFLAGS)
+check_LTLIBRARIES = libstaticrootslib.la
+libstaticrootslib_la_SOURCES = tests/staticrootslib.c
+libstaticrootslib_la_LIBADD = libgcjgc_convenience.la
+libstaticrootslib_la_LDFLAGS = -version-info 1:2:0 -no-undefined \
+				-rpath /nowhere -shared-libgcc
+libstaticrootslib_la_DEPENDENCIES = libgcjgc_convenience.la
+
 ## FIXME: we shouldn't have to do this, but automake forces us to.
 .s.lo:
 ## We use -Wp,-P to strip #line directives.  Irix `as' chokes on

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]