diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-05-17 05:30:25 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-05-17 05:30:25 +0000 |
commit | d7b8f2b7816952c96c769c62eca10c647caa3530 (patch) | |
tree | ee128f558640851fefb4f2a94c2d38f45b2ee2a0 /libgo/runtime/go-signal.c | |
parent | 8730965e4297b5f96210b2e80e70c5b302486723 (diff) | |
download | gcc-d7b8f2b7816952c96c769c62eca10c647caa3530.zip gcc-d7b8f2b7816952c96c769c62eca10c647caa3530.tar.gz gcc-d7b8f2b7816952c96c769c62eca10c647caa3530.tar.bz2 |
runtime: Print stack trace on panic or signal.
From-SVN: r187623
Diffstat (limited to 'libgo/runtime/go-signal.c')
-rw-r--r-- | libgo/runtime/go-signal.c | 54 |
1 files changed, 41 insertions, 13 deletions
diff --git a/libgo/runtime/go-signal.c b/libgo/runtime/go-signal.c index abe78c4..5d398b0 100644 --- a/libgo/runtime/go-signal.c +++ b/libgo/runtime/go-signal.c @@ -157,7 +157,6 @@ sig_handler (int sig) for (i = 0; runtime_sigtab[i].sig != -1; ++i) { - struct sigaction sa; SigTab *t; t = &runtime_sigtab[i]; @@ -177,21 +176,33 @@ sig_handler (int sig) runtime_startpanic (); - /* We should do a stack backtrace here. Until we can do that, - we reraise the signal in order to get a slightly better - report from the shell. */ + { + const char *name = NULL; - memset (&sa, 0, sizeof sa); +#ifdef HAVE_STRSIGNAL + name = strsignal (sig); +#endif - sa.sa_handler = SIG_DFL; + if (name == NULL) + runtime_printf ("Signal %d\n", sig); + else + runtime_printf ("%s\n", name); + } - i = sigemptyset (&sa.sa_mask); - __go_assert (i == 0); + runtime_printf ("\n"); - if (sigaction (sig, &sa, NULL) != 0) - abort (); + if (runtime_gotraceback ()) + { + G *g; - raise (sig); + g = runtime_g (); + runtime_traceback (g); + runtime_tracebackothers (g); + + /* The gc library calls runtime_dumpregs here, and provides + a function that prints the registers saved in context in + a readable form. */ + } runtime_exit (2); } @@ -230,12 +241,22 @@ static void sig_panic_info_handler (int sig, siginfo_t *info, void *context __attribute__ ((unused))) { - if (runtime_g () == NULL || info->si_code == SI_USER) + G *g; + + g = runtime_g (); + if (g == NULL || info->si_code == SI_USER) { sig_handler (sig); return; } + g->sig = sig; + g->sigcode0 = info->si_code; + g->sigcode1 = (uintptr_t) info->si_addr; + + /* It would be nice to set g->sigpc here as the gc library does, but + I don't know how to get it portably. */ + sig_panic_leadin (sig); switch (sig) @@ -284,12 +305,19 @@ sig_panic_info_handler (int sig, siginfo_t *info, static void sig_panic_handler (int sig) { - if (runtime_g () == NULL) + G *g; + + g = runtime_g (); + if (g == NULL) { sig_handler (sig); return; } + g->sig = sig; + g->sigcode0 = 0; + g->sigcode1 = 0; + sig_panic_leadin (sig); switch (sig) |