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] Fix boehm-gc on sparc64-linux


Unfortunately, I decided long ago to use a hard coded value
for STACKBOTTOM on sparc64-*-linux because glibc was not setting
__libc_stack_end correctly.

Now, current kernels alternate the top of the stack (for cache
coloring, security, whatever) and this breaks the fixed setting
and boehm-gc crashes very early on for even the most simplistic
test case.  Richard Henderson has had to deal with this same
exact issue on Alpha/Linux, see:

	http://gcc.gnu.org/ml/gcc-patches/2005-04/msg01310.html

As a further consequence, all of the java test cases fail for
this platform as well.  Not good.

I've at least verified two things, the failure mode for __libc_stack_end
in older glibc's and that current glibc does set it properly.
The failure mode is that it gets set to "1".

So what I've done is come up with the easiest bug fix for this problem.
I define LINUX_STACKBOTTOM, and when SPARC I check for the bug case
of __libc_stack_end being set to 1.  If it is, we fallback to the
procfs reading code (which I also verified works properly on this
platform).

There is a generic way this bug could have been checked for.  For
the procfs case, there is already a sanity check that the stack
value obtained is greater than 0x10000000.  The __libc_stack_end
could be verified against this value as well.  I considered that
approach too risky at least at this time.

At some point in the future I should convert SPARC/LINUX over to
using SEARCH_FOR_DATA_START as well.  But that is for another day.

Does anyone object to my putting a similar fix into the stable
branches (particularly 3.3, 3.4 and 4.0)?

Thanks.

2005-04-17  David S. Miller  <davem@davemloft.net>

	* include/private/gcconfig.h (sparc-linux): Use LINUX_STACKBOTTOM.
	* os_dep.c (GC_linux_stack_base): Check for bug present in some
	Sparc glibc variants where __libc_stack_end is erroneously set
	to "1".  Fallback to procfs code in that case.

Index: include/private/gcconfig.h
===================================================================
RCS file: /cvs/gcc/gcc/boehm-gc/include/private/gcconfig.h,v
retrieving revision 1.41
diff -u -p -r1.41 gcconfig.h
--- include/private/gcconfig.h	12 Apr 2005 19:48:18 -0000	1.41
+++ include/private/gcconfig.h	17 Apr 2005 21:29:30 -0000
@@ -924,12 +924,10 @@
       extern ptr_t GC_SysVGetDataStart();
 #     ifdef __arch64__
 #	define DATASTART GC_SysVGetDataStart(0x100000, _etext)
-	/* libc_stack_end is not set reliably for sparc64 */
-#       define STACKBOTTOM ((ptr_t) 0x80000000000ULL)
 #     else
 #       define DATASTART GC_SysVGetDataStart(0x10000, _etext)
-#	define LINUX_STACKBOTTOM
 #     endif
+#     define LINUX_STACKBOTTOM
 #   endif
 #   ifdef OPENBSD
 #     define OS_TYPE "OPENBSD"
Index: os_dep.c
===================================================================
RCS file: /cvs/gcc/gcc/boehm-gc/os_dep.c,v
retrieving revision 1.30
diff -u -p -r1.30 os_dep.c
--- os_dep.c	13 Aug 2004 23:05:30 -0000	1.30
+++ os_dep.c	17 Apr 2005 21:29:30 -0000
@@ -945,8 +945,17 @@ ptr_t GC_get_stack_base()
 	  } /* Otherwise it's not safe to add 16 bytes and we fall	*/
 	    /* back to using /proc.					*/
 #	else 
+#	ifdef SPARC
+	  /* Older versions of glibc for 64-bit Sparc do not set
+	   * this variable correctly, it gets set to either zero
+	   * or one.
+	   */
+	  if (__libc_stack_end != (ptr_t) (unsigned long)0x1)
+	    return __libc_stack_end;
+#	else
 	  return __libc_stack_end;
 #	endif
+#	endif
       }
     f = open("/proc/self/stat", O_RDONLY);
     if (f < 0 || STAT_READ(f, stat_buf, STAT_BUF_SIZE) < 2 * STAT_SKIP) {


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