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
2012-01-09  Harald Anlauf  <anl...@gmx.de>
	    Tobias Burnus  <bur...@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,

Reply via email to