Message ID | 4F0B3E3B.7040608@net-b.de |
---|---|
State | New |
Headers | show |
On Mon, Jan 09, 2012 at 08:21:31PM +0100, Tobias Burnus wrote: > > With the patch, one can get (cf. PR) an output to STDERR like: > > Program received signal 8 (SIGFPE): Floating-point exception. > > Backtrace for this error: > #0 0x805891F in _gfortrani_show_backtrace at backtrace.c:261 > #1 0x804951F in _gfortrani_backtrace_handler at compile_options.c:93 > #2 0xFFFFE3FF > #3 0x80493B3 in foo at gfcbug113.f90:8 > #4 0x804940B in backtrace at gfcbug113.f90:3 > > > which might be followed by the OS diagnostic, e.g. on Linux with a Bash > one gets the following to STDOUT: > > Floating point exception (core dumped) > > OK for the trunk? > OK.
On Mon, Jan 9, 2012 at 21:21, Tobias Burnus <burnus@net-b.de> wrote: > Hello, > > in GCC 4.6, gfortran printed before the backtrace, e.g., > Program received signal 8 (SIGFPE): Floating-point exception. > to STDERR followed by the backtrace. > > This was done by registering an error handler and - finishing with a > sys_exit(5). Since 4.7 with the patch for PR 48915 (comment 3) [1], GCC does > no longer print this line but just a simple: > A fatal error occurred! Backtrace for this error: > followed by the the backtrace. It then raises the signal via the default > handler. (The system might then print more information, e.g. "Floating point > exception (core dumped)", which might end up on STDOUT contrary to the > backtrace which goes to STDERR.) > > [1] Cf. runtime/compile_options.c at > http://gcc.gnu.org/viewcvs?view=revision&revision=173750 > > The attached patch by Harald Anlauf (cf. PR, minutely modified by me) > restores GCC 4.6's printing of the signal number by simply printing this > information before the back trace. (Copyright wise, the patch is simple even > as it exceeds ten lines: it mostly undoes part of Rev. 173750 [1].) > > With the patch, one can get (cf. PR) an output to STDERR like: > > Program received signal 8 (SIGFPE): Floating-point exception. > > Backtrace for this error: > #0 0x805891F in _gfortrani_show_backtrace at backtrace.c:261 > #1 0x804951F in _gfortrani_backtrace_handler at compile_options.c:93 > #2 0xFFFFE3FF > #3 0x80493B3 in foo at gfcbug113.f90:8 > #4 0x804940B in backtrace at gfcbug113.f90:3 > > > which might be followed by the OS diagnostic, e.g. on Linux with a Bash one > gets the following to STDOUT: > > Floating point exception (core dumped) > > > OK for the trunk? I see this was already Ok'ed, but still a few comments: - The integer values for the signal numbers are not standardized, hence printing them might give the user a false impression that these numbers convey some information beyond whichever SIG* macro they map to on that particular target. - It doesn't test all the signals which are actually handled, see compile_options.c:set_options(). Also, as a minor point, there's no need to have #ifdef tests for the C89 signals, again see set_options(). - The floor is now open for some enterprising person to file a bug complaining that duplicate information is printed when, as usual, stdout and stderr are output to the same device. ;-)
2012-01-09 Harald Anlauf <anlauf@gmx.de> Tobias Burnus <burnus@net-b.de> PR fortran/51197 * runtime/backtrace.c (show_backtrace): Modify wording written before the backtrace. * runtime/compile_options.c (show_signal): New function. (backtrace_handler): Use it. diff --git a/libgfortran/runtime/backtrace.c b/libgfortran/runtime/backtrace.c index e28bdcb..bb335e4 100644 --- a/libgfortran/runtime/backtrace.c +++ b/libgfortran/runtime/backtrace.c @@ -195,11 +195,11 @@ show_backtrace (void) { bt_state state; state.frame_number = 0; state.error = 0; - estr_write ("\nA fatal error occurred! Backtrace for this error:\n"); + estr_write ("\nBacktrace for this error:\n"); #if CAN_PIPE if (addr2line_path == NULL) goto fallback_noerr; diff --git a/libgfortran/runtime/compile_options.c b/libgfortran/runtime/compile_options.c index 0c139a2..aadd7eb 100644 --- a/libgfortran/runtime/compile_options.c +++ b/libgfortran/runtime/compile_options.c @@ -30,10 +30,56 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see compile_options_t compile_options; volatile sig_atomic_t fatal_error_in_progress = 0; + +/* Helper function for backtrace_handler to write information about the + received signal to stderr before actually giving the backtrace. */ +static void +show_signal (int signum) +{ + const char * name = NULL, * desc = NULL; + + switch (signum) + { +#if defined(SIGSEGV) + case SIGSEGV: + name = "SIGSEGV"; + desc = "Segmentation fault"; + break; +#endif + +#if defined(SIGBUS) + case SIGBUS: + name = "SIGBUS"; + desc = "Bus error"; + break; +#endif + +#if defined(SIGILL) + case SIGILL: + name = "SIGILL"; + desc = "Illegal instruction"; + break; +#endif + +#if defined(SIGFPE) + case SIGFPE: + name = "SIGFPE"; + desc = "Floating-point exception"; + break; +#endif + } + + if (name) + st_printf ("\nProgram received signal %d (%s): %s.\n", signum, name, desc); + else + st_printf ("\nProgram received signal %d.\n", signum); +} + + /* A signal handler to allow us to output a backtrace. */ void backtrace_handler (int signum) { /* Since this handler is established for more than one kind of signal, @@ -41,10 +87,11 @@ backtrace_handler (int signum) of signal. Use a static variable to keep track of that. */ if (fatal_error_in_progress) raise (signum); fatal_error_in_progress = 1; + show_signal (signum); show_backtrace(); /* Now reraise the signal. We reactivate the signal's default handling, which is to terminate the process. We could just call exit or abort,