[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