From 5e9c4b24de8716f6286fab4336faadd831b035e7 Mon Sep 17 00:00:00 2001 From: Mark Seaborn Date: Thu, 21 Jan 2010 14:56:44 +0000 Subject: [PATCH] Debugging: Add code to print backtrace for guest on SIGSEGV --- service_runtime/sel_main.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/service_runtime/sel_main.c b/service_runtime/sel_main.c index 033a69d5..873f0181 100644 --- a/service_runtime/sel_main.c +++ b/service_runtime/sel_main.c @@ -35,6 +35,7 @@ #include "native_client/include/portability.h" #include +#include #include #include #include @@ -171,6 +172,71 @@ static void StopForDebuggerInit (const struct NaClApp *state) #endif } +static void trace_stack(struct sigcontext_struct *regs) +{ + fprintf(stderr, " top_of_stack, code_addr=%lx\n", regs->eip); + int frame = regs->ebp; + int base = 0x10000000; /* TODO: don't hard code this */ + while(frame) { + int ret_addr = *(int *) (base + frame + 4); + int next_frame = *(int *) (base + frame); + fprintf(stderr, " stack_frame=%x, code_addr=%x\n", frame, ret_addr); + frame = next_frame; + } +} + +static void print_regs(struct sigcontext_struct *regs) +{ +#define PRINT_REG(name) \ + fprintf(stderr, " " #name "=0x%lx (%li)\n", regs->name, regs->name); + PRINT_REG(eip); + PRINT_REG(eax); + PRINT_REG(ebx); + PRINT_REG(ecx); + PRINT_REG(edx); +#undef PRINT_REG +} + +static int orig_gs; + +static void handle_signal(int arg) +{ + struct sigcontext_struct *regs = (void *) (&arg + 1); + /* Need to restore %gs even if we don't use TLS variables. + Stack protector value is fetched from %gs. */ + __asm__("mov %0, %%gs" : : "r" (orig_gs)); + /* Disable this handler. */ + signal(SIGSEGV, SIG_DFL); + fprintf(stderr, "Caught signal\n"); + print_regs(regs); + trace_stack(regs); + fprintf(stderr, "Signal handler done, exiting\n"); + _exit(1); +} + +static void set_up_signal_handler() +{ + stack_t st; + st.ss_size = 2048; + st.ss_sp = malloc(st.ss_size); + st.ss_flags = 0; + if(sigaltstack(&st, NULL) < 0) { + perror("sigaltstack"); + exit(1); + } + + __asm__("mov %%gs, %0" : "=r" (orig_gs)); + + struct sigaction act; + act.sa_handler = handle_signal; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_ONSTACK; + if(sigaction(SIGSEGV, &act, NULL) < 0) { + perror("sigaction"); + exit(1); + } +} + /* * Note that we cannot use the 3 arg declaration for main, since SDL * preprocessor defines main to SDLmain and then provides a @@ -210,6 +276,8 @@ int main(int ac, char *env_verbosity; struct GioFile log_gio; + set_up_signal_handler(); + /* do expiration check first */ #if 0 if (NaClHasExpired()) { -- 2.11.4.GIT