[boehm-gc] Use thr_stksegment to determine Solaris stack base

Rainer Orth <[email protected]>
Newsgroups gmane.comp.gcc.java.patches,gmane.comp.gcc.patches
Message-ID <[email protected]>
Since Solaris 11.1/x86, a few 32-bit boehm-gc testcases started to FAIL:

FAIL: boehm-gc.c/gctest.c -O2 execution test
FAIL: boehm-gc.c/leak_test.c -O2 execution test
FAIL: boehm-gc.c/thread_leak_test.c -O2 execution test
FAIL: boehm-gc.lib/staticrootstest.c -O2 execution test

They all SEGV on the first call to GC_mark_from.  This turns out to be a
side effect of the virtual memory system rewrite (VM 2.0) in that
Solaris version: one of the very few user-visible changes in that
release was that the 32-bit x86 stack base changed, unfortunately
without updating the USRSTACK definition in <sys/vmparam.h>.

Unlike the boehm-gc 6.6-based version in the gcc tree, the failure
doesn't happen with gc 7.2c.  It turns out that this is case since that
version uses the thr_stksegment(3C) function instead of the macro.  This
function exists since at least Solaris 2.5.1 and has the additional
advantage of also working with ASLR also introduced with VM2, where a
fixed stack base is wrong.

This patch fixes the failures by backporting the use of thr_stksegment
from gc 7.2c.

Bootstrapped without regressions on i386-pc-solaris2.{9,10,11} and
sparc-sun-solaris2.{9,10,11}, fixes the i386-pc-solaris2.11 failures.

Ok for mainline?

	Rainer


2013-03-04  Rainer Orth  <[email protected]>

	* os_dep.c [SOLARIS_STACKBOTTOM] (GC_solaris_stack_base): New
	function.
	[!BEOS && !AMIGA && !MSWIN32 && !MSWINCE && !OS2 && !NOSYS &&
	!ECOS] (GC_get_stack_base): Use it.
	* include/private/gcconfig.h [SPARC && SUNOS5]
	(SOLARIS_STACKBOTTOM): Define.
	(STACKBOTTOM, HEURISTIC2): Remove.
	[I386 && SUNOS5]
	(SOLARIS_STACKBOTTOM): Define.
	(STACKBOTTOM): Remove.


-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University
sol2-boehm-gc-stack.patch (text/x-patch, 4.3 KB)
# HG changeset patch
# Parent 3b82ec434332de00d9006fa3985dd9180c0cf499
Use thr_stksegment to determine Solaris stack base

diff --git a/boehm-gc/include/private/gcconfig.h b/boehm-gc/include/private/gcconfig.h
--- a/boehm-gc/include/private/gcconfig.h
+++ b/boehm-gc/include/private/gcconfig.h
@@ -927,18 +927,7 @@
 #	  define HEAP_START DATAEND
 #       endif
 #	define PROC_VDB
-/*	HEURISTIC1 reportedly no longer works under 2.7.  		*/
-/*  	HEURISTIC2 probably works, but this appears to be preferable.	*/
-/*	Apparently USRSTACK is defined to be USERLIMIT, but in some	*/
-/* 	installations that's undefined.  We work around this with a	*/
-/*	gross hack:							*/
-#       include <sys/vmparam.h>
-#	ifdef USERLIMIT
-	  /* This should work everywhere, but doesn't.	*/
-#	  define STACKBOTTOM USRSTACK
-#       else
-#	  define HEURISTIC2
-#       endif
+#	define SOLARIS_STACKBOTTOM
 #	include <unistd.h>
 #       define GETPAGESIZE()  sysconf(_SC_PAGESIZE)
 		/* getpagesize() appeared to be missing from at least one */
@@ -1067,13 +1056,7 @@
   	extern ptr_t GC_SysVGetDataStart();
 #       define DATASTART GC_SysVGetDataStart(0x1000, _etext)
 #	define DATAEND (_end)
-/*	# define STACKBOTTOM ((ptr_t)(_start)) worked through 2.7,  	*/
-/*      but reportedly breaks under 2.8.  It appears that the stack	*/
-/* 	base is a property of the executable, so this should not break	*/
-/* 	old executables.						*/
-/*  	HEURISTIC2 probably works, but this appears to be preferable.	*/
-#       include <sys/vm.h>
-#	define STACKBOTTOM USRSTACK
+#	define SOLARIS_STACKBOTTOM
 /* At least in Solaris 2.5, PROC_VDB gives wrong values for dirty bits. */
 /* It appears to be fixed in 2.8 and 2.9.				*/
 #	ifdef SOLARIS25_PROC_VDB_BUG_FIXED
diff --git a/boehm-gc/os_dep.c b/boehm-gc/os_dep.c
--- a/boehm-gc/os_dep.c
+++ b/boehm-gc/os_dep.c
@@ -1008,13 +1008,62 @@ ptr_t GC_get_stack_base()
 
 #endif /* FREEBSD_STACKBOTTOM */
 
+#ifdef SOLARIS_STACKBOTTOM
+
+# include <thread.h>
+# include <signal.h>
+# include <pthread.h>
+
+  /* These variables are used to cache ss_sp value for the primordial   */
+  /* thread (it's better not to call thr_stksegment() twice for this    */
+  /* thread - see JDK bug #4352906).                                    */
+  static pthread_t stackbase_main_self = 0;
+                        /* 0 means stackbase_main_ss_sp value is unset. */
+  static void *stackbase_main_ss_sp = NULL;
+
+  ptr_t GC_solaris_stack_base(void)
+  {
+    stack_t s;
+    pthread_t self = pthread_self();
+    if (self == stackbase_main_self)
+      {
+        /* If the client calls GC_get_stack_base() from the main thread */
+        /* then just return the cached value.                           */
+        GC_ASSERT(stackbase_main_ss_sp != NULL);
+        return stackbase_main_ss_sp;
+      }
+
+    if (thr_stksegment(&s)) {
+      /* According to the manual, the only failure error code returned  */
+      /* is EAGAIN meaning "the information is not available due to the */
+      /* thread is not yet completely initialized or it is an internal  */
+      /* thread" - this shouldn't happen here.                          */
+      ABORT("thr_stksegment failed");
+    }
+    /* s.ss_sp holds the pointer to the stack bottom. */
+    GC_ASSERT((void *)&s HOTTER_THAN s.ss_sp);
+
+    if (!stackbase_main_self)
+      {
+        /* Cache the stack base value for the primordial thread (this   */
+        /* is done during GC_init, so there is no race).                */
+        stackbase_main_ss_sp = s.ss_sp;
+        stackbase_main_self = self;
+      }
+
+    return s.ss_sp;
+  }
+
+#endif /* GC_SOLARIS_THREADS */
+
 #if !defined(BEOS) && !defined(AMIGA) && !defined(MSWIN32) \
     && !defined(MSWINCE) && !defined(OS2) && !defined(NOSYS) && !defined(ECOS)
 
 ptr_t GC_get_stack_base()
 {
 #   if defined(HEURISTIC1) || defined(HEURISTIC2) || \
-       defined(LINUX_STACKBOTTOM) || defined(FREEBSD_STACKBOTTOM)
+       defined(LINUX_STACKBOTTOM) || defined(FREEBSD_STACKBOTTOM) || \
+       defined(SOLARIS_STACKBOTTOM)       
     word dummy;
     ptr_t result;
 #   endif
@@ -1040,6 +1089,9 @@ ptr_t GC_get_stack_base()
 #	ifdef FREEBSD_STACKBOTTOM
 	   result = GC_freebsd_stack_base();
 #	endif
+#	ifdef SOLARIS_STACKBOTTOM
+	   result = GC_solaris_stack_base();
+#	endif
 #	ifdef HEURISTIC2
 #	    ifdef STACK_GROWS_DOWN
 		result = GC_find_limit((ptr_t)(&dummy), TRUE);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.