[Gd-chatter] r11491 - trunk/fundev/sources/lib/run-time/pentium-linux

hannes at gwydiondylan.org hannes at gwydiondylan.org
Fri Nov 16 21:38:05 CET 2007


Author: hannes
Date: Fri Nov 16 21:38:05 2007
New Revision: 11491

Modified:
   trunk/fundev/sources/lib/run-time/pentium-linux/x86-linux-exceptions.c
Log:
Job: fd

integrate a stack tracer as default trap handler. This gives
a stack trace on a runtime error. Of course, the output could
be improved.

# ~/error-test/bin/errotest 
fnord
0xb7e3a7e7 (/home/hannes/error-test/lib/libdylan.so)
0xb7e3a86b (/home/hannes/error-test/lib/libdylan.so)
__kernel_sigreturn+0 ()
Kinvoke_debuggerVKiMM1I+53 (/home/hannes/error-test/lib/libdylan.so)
Khandle_missed_dispatch_1VKgI+567 (/home/hannes/error-test/lib/libdylan.so)
0xb7e3782b (/home/hannes/error-test/lib/libdylan.so)
Kdefault_handlerVKdMM1I+26 (/home/hannes/error-test/lib/libdylan.so)
Khandle_missed_dispatch_1VKgI+567 (/home/hannes/error-test/lib/libdylan.so)
0xb7e3782b (/home/hannes/error-test/lib/libdylan.so)
0xb7de7744 (/home/hannes/error-test/lib/libdylan.so)
0xb7de77d1 (/home/hannes/error-test/lib/libdylan.so)
Khandle_missed_dispatch_1VKgI+567 (/home/hannes/error-test/lib/libdylan.so)
0xb7e378ca (/home/hannes/error-test/lib/libdylan.so)
KerrorVKdMM0I+58 (/home/hannes/error-test/lib/libdylan.so)
Khandle_missed_dispatch_1VKgI+567 (/home/hannes/error-test/lib/libdylan.so)
0xb7e378ca (/home/hannes/error-test/lib/libdylan.so)
KmainVerrotestI+26 (/home/hannes/error-test/lib/liberrotest.so)
_Init_errotest__X_errotest_for_user_0+28 (/home/hannes/error-test/lib/liberrotest.so)
_Init_errotest__X_errotest_for_user+8 (/home/hannes/error-test/lib/liberrotest.so)
0xb7f17497 (/home/hannes/error-test/lib/liberrotest.so)
0xb7f174e8 (/home/hannes/error-test/lib/liberrotest.so)
ProtTramp+22 (/home/hannes/error-test/lib/libdylan.so)
mps_tramp+38 (/home/hannes/error-test/lib/libdylan.so)
dylan_init_thread+233 (/home/hannes/error-test/lib/libdylan.so)
0xb7f17526 (/home/hannes/error-test/lib/liberrotest.so)
0xb7f17583 (/home/hannes/error-test/lib/liberrotest.so)
0x804864e (/home/hannes/error-test/bin/errotest)
__libc_start_main+224 (/lib/tls/i686/cmov/libc.so.6)
0x80485d1 (/home/hannes/error-test/bin/errotest)
Abort (core dumped)


Modified: trunk/fundev/sources/lib/run-time/pentium-linux/x86-linux-exceptions.c
==============================================================================
--- trunk/fundev/sources/lib/run-time/pentium-linux/x86-linux-exceptions.c	(original)
+++ trunk/fundev/sources/lib/run-time/pentium-linux/x86-linux-exceptions.c	Fri Nov 16 21:38:05 2007
@@ -28,31 +28,39 @@
 #define EXCEPTION_PREAMBLE() \
   struct sigaction oldFPEHandler; \
   struct sigaction oldSEGVHandler; \
+  struct sigaction oldTRAPHandler; \
   void doFPEHandler (int signum, struct sigcontext sc) { \
     DylanFPEHandler(oldFPEHandler.sa_handler, signum, sc); \
   } \
   void doSEGVHandler (int signum, struct sigcontext sc) { \
     DylanSEGVHandler(oldSEGVHandler.sa_handler, signum, sc); \
   } \
+  void doTRAPHandler (int signum, struct sigcontext sc) { \
+    DylanTRAPHandler(oldTRAPHandler.sa_handler, signum, sc);	\
+  } \
   oldFPEHandler.sa_handler = (sighandler_t)doFPEHandler; \
   oldSEGVHandler.sa_handler = (sighandler_t)doSEGVHandler; \
-  EstablishDylanExceptionHandlers(&oldFPEHandler, &oldSEGVHandler); \
+  oldTRAPHandler.sa_handler = (sighandler_t)doTRAPHandler; \
+  EstablishDylanExceptionHandlers(&oldFPEHandler, &oldSEGVHandler, &oldTRAPHandler);	\
   {
 
 #define EXCEPTION_POSTAMBLE() \
   } \
-  RemoveDylanExceptionHandlers(&oldFPEHandler, &oldSEGVHandler);
+  RemoveDylanExceptionHandlers(&oldFPEHandler, &oldSEGVHandler, &oldTRAPHandler);
 
 typedef void (* SIG_SIGCONTEXT)(int, struct sigcontext);
 
 static void DylanFPEHandler (sighandler_t, int, struct sigcontext);
 static void DylanSEGVHandler (sighandler_t, int, struct sigcontext);
+static void DylanTRAPHandler (sighandler_t, int, struct sigcontext);
 
 static void EstablishDylanExceptionHandlers (struct sigaction * oldFPEHandler,
-					     struct sigaction * oldSEGVHandler)
+					     struct sigaction * oldSEGVHandler,
+					     struct sigaction * oldTRAPHandler)
 {
   struct sigaction newFPEHandler;
   struct sigaction newSEGVHandler;
+  struct sigaction newTRAPHandler;
 
   sigset_t set, oldset;
 
@@ -68,18 +76,25 @@
   sigaction(SIGSEGV, &newSEGVHandler, oldSEGVHandler);
 #endif
 
+  newTRAPHandler.sa_handler = oldTRAPHandler->sa_handler;
+  sigemptyset(&newTRAPHandler.sa_mask);
+  newTRAPHandler.sa_flags = 0;
+  sigaction(SIGTRAP, &newTRAPHandler, oldTRAPHandler);
+
   sigemptyset(&set);
   sigaddset(&set, SIGPIPE);
   sigprocmask(SIG_BLOCK, &set, &oldset);
 }
 
 static void RemoveDylanExceptionHandlers (struct sigaction * oldFPEHandler,
-					  struct sigaction * oldSEGVHandler)
+					  struct sigaction * oldSEGVHandler,
+					  struct sigaction * oldTRAPHandler)
 {
   sigaction(SIGFPE, oldFPEHandler, NULL);
 #if 0
   sigaction(SIGSEGV, oldSEGVHandler, NULL);
 #endif
+  sigaction(SIGTRAP, oldTRAPHandler, NULL);
 }
 
 
@@ -175,3 +190,45 @@
 
   return;
 }
+
+static void DylanTRAPHandler (sighandler_t oldHandler, int signum, struct sigcontext sc)
+{
+  walkstack();
+  (*(SIG_SIGCONTEXT)oldHandler)(signum, sc);
+  return;
+}
+
+#include <stdio.h>
+#include <dlfcn.h>
+
+int getebp () {
+    int ebp;
+    asm("mov (%%ebp), %0"
+        :"=r"(ebp));
+    return ebp;
+};
+
+void walkstack() {
+  int ebp = getebp();
+  int eip;
+  int rc;
+  Dl_info info;
+
+  while(ebp) {
+    eip = *((int*)ebp + 1);
+    rc = dladdr((void*)eip, &info);
+    if (!rc||(!info.dli_sname && !info.dli_fname)) {
+      printf("0x%x (unknown)\n");
+    } else {
+      if (!info.dli_sname) {
+        printf("0x%x (%s)\n", eip, info.dli_fname);
+      } else {
+        printf("%s+%i (%s)\n",
+               info.dli_sname,
+	       eip - (int)info.dli_saddr,
+	       info.dli_fname);
+      }
+    }
+    ebp = *((int*)ebp);
+  }
+}



More information about the chatter mailing list