diff mbox

[Fortran] PR51197 - print signal number before backtrace [RFC]

Message ID 4F0B3E3B.7040608@net-b.de
State New
Headers show

Commit Message

Tobias Burnus Jan. 9, 2012, 7:21 p.m. UTC
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?

Tobias

Comments

Steve Kargl Jan. 9, 2012, 7:35 p.m. UTC | #1
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.
Janne Blomqvist Jan. 9, 2012, 8:32 p.m. UTC | #2
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. ;-)
diff mbox

Patch

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,