[kaffe] CVS kaffe (guilhem): Implementing possibilities to use other heuristics to detect stack boundaries.

Kaffe CVS cvs-commits at kaffe.org
Sun May 9 07:50:02 PDT 2004


PatchSet 4722 
Date: 2004/05/09 14:20:10
Author: guilhem
Branch: HEAD
Tag: (none) 
Log:
Implementing possibilities to use other heuristics to detect stack boundaries.

        * config/i386/linux/md.c, config/i386/linux/md.h:
        New machine dependent function mdGetStackBase(). KAFFEMD_STACKBASE
        is defined on ix86/linux now. If the user is running a GLIBC, then use
        __libc_stack_end.

        * kaffe/kaffevm/systems/unix-jthreads/signal.c:
        (detectStackBoundaries) Updated heuristics on detecting
        stack boundaries. The code now accepts either KAFFEMD_STACKBASE,
        KAFFEMD_STACKEND, stack limit finder or the old heuristic.

        * FAQ/FAQ.kaffemd: Missing file from a previous check in.

Members: 
	ChangeLog:1.2296->1.2297 
	FAQ/FAQ.kaffemd:INITIAL->1.1 
	config/i386/linux/md.c:1.1->1.2 
	config/i386/linux/md.h:1.11->1.12 
	kaffe/kaffevm/systems/unix-jthreads/jsignal.h:1.4->1.5 
	kaffe/kaffevm/systems/unix-jthreads/signal.c:1.16->1.17 

Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.2296 kaffe/ChangeLog:1.2297
--- kaffe/ChangeLog:1.2296	Thu May  6 10:20:31 2004
+++ kaffe/ChangeLog	Sun May  9 14:20:10 2004
@@ -1,3 +1,17 @@
+2004-05-07  Guilhem Lavaux <guilhem at kaffe.org>
+
+	* config/i386/linux/md.c, config/i386/linux/md.h:
+	New machine dependent function mdGetStackBase(). KAFFEMD_STACKBASE
+	is defined on ix86/linux now. If the user is running a GLIBC, then use
+	__libc_stack_end.
+
+	* kaffe/kaffevm/systems/unix-jthreads/signal.c:
+	(detectStackBoundaries)	Updated heuristics on detecting
+	stack boundaries. The code now accepts either KAFFEMD_STACKBASE,
+	KAFFEMD_STACKEND, stack limit finder or the old heuristic.
+
+	* FAQ/FAQ.kaffemd: Missing file from a previous check in.
+
 2004-05-06  Dalibor Topic  <robilad at kaffe.org>
 
 	* libraries/javalib/java/text/Format.java:
===================================================================
Checking out kaffe/FAQ/FAQ.kaffemd
RCS:  /home/cvs/kaffe/kaffe/FAQ/FAQ.kaffemd,v
VERS: 1.1
***************
--- /dev/null	Sun Aug  4 19:57:58 2002
+++ kaffe/FAQ/FAQ.kaffemd	Sun May  9 14:23:57 2004
@@ -0,0 +1,32 @@
+FAQ for defines
+===============
+
+Here are the defines to put in config/*/*/md.h to enable features
+in kaffe.
+
+KAFFEMD_PAGESIZE
+----------------
+
+This macro is to be defined if the OS supports mdGetPageSize().
+mdGetPageSize() returns the current page size for the operating system.
+
+KAFFEMD_STACKOVERFLOW
+---------------------
+
+This macro is to be defined if the operating system supports stack overflow 
+reporting. This macro should require that at least SA_ONSTACK, STACK_POINTER 
+and HAVE_SIGALTSTACK are defined. But if the operating system is badly supported
+on the architecture this can be left undefined and kaffe will keep the old
+behaviour.
+
+KAFFEMD_STACKBASE
+-----------------
+
+This macro is to be defined is the platform supports mdGetStackBase(). This
+function returns a pointer to the bottom of the stack.
+
+KAFFEMD_STACKEND
+-----------------
+
+This macro is to be defined is the platform supports mdGetStackEnd(). This
+function returns a pointer to the end of the stack.
Index: kaffe/config/i386/linux/md.c
diff -u kaffe/config/i386/linux/md.c:1.1 kaffe/config/i386/linux/md.c:1.2
--- kaffe/config/i386/linux/md.c:1.1	Tue Mar 31 19:10:53 1998
+++ kaffe/config/i386/linux/md.c	Sun May  9 14:20:12 2004
@@ -11,6 +11,9 @@
 
 #include "config.h"
 #include <malloc.h>
+#if defined(HAVE_FEATURES_H)
+#include <features.h>
+#endif
 
 void
 init_md(void)
@@ -19,3 +22,12 @@
 	mallopt(M_MMAP_MAX, 0);
 #endif
 }
+
+#if defined(__GLIBC__)
+extern void * __libc_stack_end;
+
+void *mdGetStackBase(void)
+{
+  return __libc_stack_end;
+}
+#endif
Index: kaffe/config/i386/linux/md.h
diff -u kaffe/config/i386/linux/md.h:1.11 kaffe/config/i386/linux/md.h:1.12
--- kaffe/config/i386/linux/md.h:1.11	Wed Apr 28 12:01:47 2004
+++ kaffe/config/i386/linux/md.h	Sun May  9 14:20:12 2004
@@ -90,6 +90,11 @@
 }
 #endif
 
+#if defined(__GLIBC__)
+#define KAFFEMD_STACKBASE
+extern void *mdGetStackBase(void);
+#endif
+
 #if defined(TRANSLATOR)
 #include "jit-md.h"
 #endif
Index: kaffe/kaffe/kaffevm/systems/unix-jthreads/jsignal.h
diff -u kaffe/kaffe/kaffevm/systems/unix-jthreads/jsignal.h:1.4 kaffe/kaffe/kaffevm/systems/unix-jthreads/jsignal.h:1.5
--- kaffe/kaffe/kaffevm/systems/unix-jthreads/jsignal.h:1.4	Thu Apr 22 16:28:16 2004
+++ kaffe/kaffe/kaffevm/systems/unix-jthreads/jsignal.h	Sun May  9 14:20:12 2004
@@ -45,6 +45,6 @@
 void unblockAsyncSignals(void);
 void blockAsyncSignals(void);
 
-void detectStackBoudaries(jthread jtid, int mainThreadStackSize);
+void detectStackBoundaries(jthread_t jtid, int mainThreadStackSize);
 
 #endif /* UNIXJTHREAD_SIGNAL_H */
Index: kaffe/kaffe/kaffevm/systems/unix-jthreads/signal.c
diff -u kaffe/kaffe/kaffevm/systems/unix-jthreads/signal.c:1.16 kaffe/kaffe/kaffevm/systems/unix-jthreads/signal.c:1.17
--- kaffe/kaffe/kaffevm/systems/unix-jthreads/signal.c:1.16	Sat Apr 24 19:48:10 2004
+++ kaffe/kaffe/kaffevm/systems/unix-jthreads/signal.c	Sun May  9 14:20:12 2004
@@ -345,62 +345,143 @@
 	
 }
 
-#if defined(STACK_POINTER) && defined(SA_ONSTACK) && defined(HAVE_SIGALTSTACK)
+#if defined(HAVE_SIGALTSTACK) && defined(SA_ONSTACK)
+static void
+setupSigAltStack(void)
+{
+        STACK_STRUCT newstack;
 
-static JTHREAD_JMPBUF outOfLoop;
-static void *stackPointer;
+	/*
+	 * Signals has to have their own stack so we can solve
+	 * stack problems.
+	 */
+	newstack.ss_size = THREADSTACKSIZE;
+	newstack.ss_flags = 0;
+	newstack.ss_sp = KMALLOC(newstack.ss_size);
+	if (sigaltstack(&newstack, NULL) < 0)
+	  {
+	    dprintf("Unexpected error calling sigaltstack: %s\n",
+		    SYS_ERROR(errno));
+	    EXIT(1);
+	  }
+}
+#else
+static void
+setupSigAltStack(void)
+{
+}
+#endif
+
+/* ----------------------------------------------------------------------
+ * STACK BOUNDARY DETECTORS
+ * ----------------------------------------------------------------------
+ */
+
+#if defined(KAFFEMD_STACKBASE) // STACK_POINTER
 
 /*
- * This function intends to create a stack overflow error so we can evaluate
- * the stack boundaries. Unfortunately, gcc optimizes it here. This is the
- * purpose of the dummy variable a.
- */
-static void 
-infiniteLoop()
-{
-  int a;
-  infiniteLoop();
-  a = 0;
+ * The OS gives us the stack base. Get it and adjust the pointers.
+ */
+
+void
+detectStackBoundaries(jthread_t jtid, int mainThreadStackSize)
+{
+        void *stackPointer;
+
+	stackPointer = mdGetStackBase();
+
+	setupSigAltStack();
+
+#if defined(STACK_GROWS_UP)
+	jtid->stackBase = stackPointer;
+	jtid->stackEnd = (char *)jtid->stackBase + mainThreadStackSize;
+        jtid->restorePoint = jtid->stackEnd;
+#else
+	jtid->stackEnd = stackPointer;
+        jtid->stackBase = (char *) jtid->stackEnd - mainThreadStackSize;
+        jtid->restorePoint = jtid->stackBase;
+#endif
+
 }
 
+#elif defined(KAFFEMD_STACKEND) // KAFFEMD_STACKBASE
+
+/*
+ * Here the OS gives us the position of the end of stack. Get it
+ * and adjust our internal pointers.
+ */
+
+void
+detectStackBoundaries(jthread_t jtid, int mainThreadStackSize)
+{
+        void *stackPointer;
+
+	setupSigAltStack();
+
+	stackPointer = mdGetStackEnd();
+	fprintf(stderr,"stackPointer=%p\n", stackPointer);
+
+#if defined(STACK_GROWS_UP)
+	jtid->stackEnd = stackPointer;
+	jtid->stackBase = (char *)jtid->stackEnd - mainThreadStackSize;
+        jtid->restorePoint = jtid->stackEnd;
+#else
+	jtid->stackBase = stackPointer;
+        jtid->stackEnd = (char *) jtid->stackBase + mainThreadStackSize;
+        jtid->restorePoint = jtid->stackBase;
+#endif
+}
+
+#elif defined(STACK_POINTER) && defined(SA_ONSTACK) && defined(HAVE_SIGALTSTACK) && !defined(KAFFEMD_BUGGY_STACK_OVERFLOW)
+
+static JTHREAD_JMPBUF outOfLoop;
+
 /*
  * This function is called by the system when we go beyond stack boundaries
  * in infiniteLoop. We get the stack address using the stack pointer register
  * and then go back in detectStackBoundaries() using the old stack.
  */
-static void
-stackOverflowDetector(SIGNAL_ARGS(sig, sc))
+static void NONRETURNING
+stackOverflowDetector(SIGNAL_ARGS(sig UNUSED, sc))
 {
-  stackPointer = (void *)STACK_POINTER(GET_SIGNAL_CONTEXT_POINTER(sc));
   unblockSignal(SIGSEGV);
   JTHREAD_LONGJMP(outOfLoop, 1);
 }
-#endif
 
+void kaffeNoopFunc(char c UNUSED)
+{
+}
+
+/*
+ * This is the first type of heuristic we can use to guess the boundaries.
+ * Here we are provoking a SIGSEGV by overflowing the stack. Then we get
+ * the faulty adress directly.
+ */
 void
 detectStackBoundaries(jthread_t jtid, int mainThreadStackSize)
 {
-#if defined(STACK_POINTER) && defined(SA_ONSTACK) && defined(HAVE_SIGALTSTACK)
-        STACK_STRUCT newstack;
+	char *guessPointer;
+
+	setupSigAltStack();
 
-	/*
-	 * Signals has to have their own stack so we can solve
-	 * stack problems.
-	 */
-	newstack.ss_size = THREADSTACKSIZE;
-	newstack.ss_flags = 0;
-	newstack.ss_sp = KMALLOC(newstack.ss_size);
-	if (sigaltstack(&newstack, NULL) < 0)
-	  {
-	    dprintf("Unexpected error calling sigaltstack: %s\n",
-		    SYS_ERROR(errno));
-	    EXIT(1);
-	  }
-	
 	registerSignalHandler(SIGSEGV, stackOverflowDetector, false);
 	
 	if (JTHREAD_SETJMP(outOfLoop) == 0)
-	  infiniteLoop();
+	{
+	  unsigned int pageSize = getpagesize();
+
+	  guessPointer = (char *)((uintp)(&jtid) & ~(pageSize-1));
+	  
+	  while (1)
+	  {
+#if defined(STACK_GROWS_UP)
+	    guessPointer -= pageSize;
+#else
+	    guessPointer += pageSize;
+#endif
+	    kaffeNoopFunc(*guessPointer);
+	  }
+	}
 
 	/* Here we have detected one the boundary of the stack.
 	 * If stack grows up then it is the upper boundary. In the other
@@ -408,26 +489,35 @@
 	 * may guess the other boundary.
 	 */
 #if defined(STACK_GROWS_UP)
-	jtid->stackEnd = stackPointer;
-	jtid->stackBase = (char *)jtid->stackEnd - mainThreadStackSize;
+	jtid->stackBase = guessPointer;
+	jtid->stackEnd = (char *)jtid->stackBase + mainThreadStackSize;
 	jtid->restorePoint = jtid->stackEnd;
 #else
-	jtid->stackBase = stackPointer;
-	jtid->stackEnd = (char *)jtid->stackBase + mainThreadStackSize;
+	jtid->stackEnd = guessPointer;
+	jtid->stackBase = (char *)jtid->stackEnd - mainThreadStackSize;
 	jtid->restorePoint = jtid->stackBase;
 #endif
+}
 
-#else // STACK_POINTER
+#else
+
+/*
+ * This is the worse heuristic in terms of precision. But
+ * this may be the only one working on this platform.
+ */
 
+void
+detectStackBoundaries(jthread_t jtid, int mainThreadStackSize)
+{
 #if defined(STACK_GROWS_UP)
 	jtid->stackBase = (void*)(uintp)(&jtid - 0x100);
-	jtid->stackEnd = jtid->stackBase + mainThreadStackSize;
+	jtid->stackEnd = (char *)jtid->stackBase + mainThreadStackSize;
         jtid->restorePoint = jtid->stackEnd;
 #else
 	jtid->stackEnd = (void*)(uintp)(&jtid + 0x100);
         jtid->stackBase = (char *) jtid->stackEnd - mainThreadStackSize;
         jtid->restorePoint = jtid->stackBase;
 #endif
+}
 
 #endif
-}




More information about the kaffe mailing list