This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java 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: work around PR 13212


I'm checking this in (or Jakub is) on the 4.1 branch and the trunk.

This patch works around PR 13212 (for Linux native builds).

The issue occurs when some 3rd party .so, which doesn't use the
wrapped pthread_create, is loaded.  If code in this .so makes a new
thread, and executes java code from there, we won't know the stack
bounds and will run into trouble.

This occurs when running Eclipse.

The fix works by redefining pthread_create in the GC.

I call this a workaround because it still won't support all possible
use cases -- in particular, dynamically loading libgcj.so into a
running application still won't have the desired effect.

Tom

2006-02-04  Jakub Jelinek  <jakub@redhat.com>
	    Anthony Green  <green@redhat.com>
	    Tom Tromey  <tromey@redhat.com>

	* include/gc_ext_config.h.in: Added GC_PTHREAD_SYM_VERSION.
	* include/gc_config.h.in: Rebuilt.
	* include/gc_pthread_redirects.h (pthread_create): Conditionally
	define.
	* pthread_support.c (pthread_create_): New global.
	(constr): New function.
	(pthread_create): Conditionally renamed.
	* configure: Rebuilt.
	* configure.ac (GC_PTHREAD_SYM_VERSION): Define.

--- boehm-gc/configure.ac.jj	2006-01-27 18:44:05.000000000 -0500
+++ boehm-gc/configure.ac	2006-02-04 12:51:19.000000000 -0500
@@ -450,6 +450,25 @@ if test "${gc_use_mmap}" = "yes"; then
   AC_DEFINE(USE_MMAP, 1, [use MMAP instead of sbrk to get new memory])
 fi
 
+symver=
+case "$target" in
+  *-*-linux* )
+    cat > conftest.c <<EOF
+#include <pthread.h>
+void *tf (void *arg) { (void) arg; return NULL; }
+int main (void) { pthread_t th; pthread_create (&th, NULL, tf, NULL); return 0; }
+EOF
+    if $CC $CFLAGS -pthread -o conftest conftest.c > /dev/null 2>&1; then
+      symver=`readelf -s conftest 2> /dev/null | sed -n '/UND pthread_create@/{s/^.*@//;s/ .*$//;p;q}'`
+    fi
+    rm -f conftest conftest.c
+    ;;
+esac
+if test -n "$symver"; then
+  AC_DEFINE_UNQUOTED(GC_PTHREAD_SYM_VERSION, "$symver", [symbol version of pthread_create])
+fi
+
+
 if test -n "$with_cross_host" &&
    test x"$with_cross_host" != x"no"; then
   toolexecdir='$(exec_prefix)/$(target_noncanonical)'
--- boehm-gc/include/gc_pthread_redirects.h.jj	2006-01-27 18:44:03.000000000 -0500
+++ boehm-gc/include/gc_pthread_redirects.h	2006-02-04 12:46:31.000000000 -0500
@@ -68,7 +68,9 @@
 # undef pthread_detach
 #endif
 
+#ifndef GC_PTHREAD_SYM_VERSION
 # define pthread_create GC_pthread_create
+#endif
 # define pthread_join GC_pthread_join
 # define pthread_detach GC_pthread_detach
 
--- boehm-gc/include/gc_ext_config.h.in.jj	2006-01-27 18:44:03.000000000 -0500
+++ boehm-gc/include/gc_ext_config.h.in	2006-02-04 12:46:31.000000000 -0500
@@ -3,3 +3,5 @@ external clients that do not want to inc
 is used by libjava/include/boehm-gc.h. */
 
 #undef THREAD_LOCAL_ALLOC
+
+#undef GC_PTHREAD_SYM_VERSION
--- boehm-gc/include/gc_config.h.in.jj	2006-01-27 18:44:03.000000000 -0500
+++ boehm-gc/include/gc_config.h.in	2006-02-04 12:46:31.000000000 -0500
@@ -45,6 +45,9 @@
 /* support for Tru64 pthreads */
 #undef GC_OSF1_THREADS
 
+/* symbol version of pthread_create */
+#undef GC_PTHREAD_SYM_VERSION
+
 /* support for Solaris pthreads */
 #undef GC_SOLARIS_PTHREADS
 
--- boehm-gc/configure.jj	2006-01-27 18:44:05.000000000 -0500
+++ boehm-gc/configure	2006-02-04 12:51:31.000000000 -0500
@@ -6627,6 +6627,29 @@ _ACEOF
 
 fi
 
+symver=
+case "$target" in
+  *-*-linux* )
+    cat > conftest.c <<EOF
+#include <pthread.h>
+void *tf (void *arg) { (void) arg; return NULL; }
+int main (void) { pthread_t th; pthread_create (&th, NULL, tf, NULL); return 0; }
+EOF
+    if $CC $CFLAGS -pthread -o conftest conftest.c > /dev/null 2>&1; then
+      symver=`readelf -s conftest 2> /dev/null | sed -n '/UND pthread_create@/{s/^.*@//;s/ .*$//;p;q}'`
+    fi
+    rm -f conftest conftest.c
+    ;;
+esac
+if test -n "$symver"; then
+
+cat >>confdefs.h <<_ACEOF
+#define GC_PTHREAD_SYM_VERSION "$symver"
+_ACEOF
+
+fi
+
+
 if test -n "$with_cross_host" &&
    test x"$with_cross_host" != x"no"; then
   toolexecdir='$(exec_prefix)/$(target_noncanonical)'
--- boehm-gc/pthread_support.c.jj	2006-01-27 18:44:05.000000000 -0500
+++ boehm-gc/pthread_support.c	2006-02-04 12:46:31.000000000 -0500
@@ -47,6 +47,9 @@
 /*#define DEBUG_THREADS 1*/
 /*#define GC_ASSERTIONS*/
 
+#define _GNU_SOURCE
+#include <dlfcn.h>
+
 # include "gc.h"
 # include "private/pthread_support.h"
 
@@ -1194,8 +1197,37 @@ void * GC_start_routine(void * arg)
     return(result);
 }
 
+#ifdef GC_PTHREAD_SYM_VERSION
+
+/* Force constr to execute prior to main().  */
+static void constr (void) __attribute__ ((constructor));
+
+static int
+(*pthread_create_)(pthread_t *new_thread,
+		   const pthread_attr_t *attr_in,
+		   void * (*thread_execp)(void *), void *arg);
+
+static void
+constr (void)
+{
+  /* Get a pointer to the real pthread_create.  */
+  pthread_create_ = dlvsym (RTLD_NEXT, "pthread_create",
+			    GC_PTHREAD_SYM_VERSION);
+}
+
+#define GC_PTHREAD_CREATE_NAME pthread_create
+#define GC_PTHREAD_REAL_NAME (*pthread_create_)
+
+#else
+
+#define GC_PTHREAD_CREATE_NAME WRAP_FUNC(pthread_create)
+#define GC_PTHREAD_REAL_NAME REAL_FUNC(pthread_create)
+
+#endif
+
+
 int
-WRAP_FUNC(pthread_create)(pthread_t *new_thread,
+GC_PTHREAD_CREATE_NAME(pthread_t *new_thread,
 		  const pthread_attr_t *attr,
                   void *(*start_routine)(void *), void *arg)
 {
@@ -1250,7 +1282,7 @@ WRAP_FUNC(pthread_create)(pthread_t *new
 		   pthread_self());
 #   endif
 
-    result = REAL_FUNC(pthread_create)(new_thread, attr, GC_start_routine, si);
+    result = GC_PTHREAD_REAL_NAME(new_thread, attr, GC_start_routine, si);
 
 #   ifdef DEBUG_THREADS
         GC_printf1("Started thread 0x%X\n", *new_thread);


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