Bug 31189 - Support backtracing for non-library errors
Summary: Support backtracing for non-library errors
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.3.0
: P3 enhancement
Target Milestone: ---
Assignee: Francois-Xavier Coudert
URL: http://gcc.gnu.org/ml/gcc-patches/200...
Keywords: diagnostic, patch
: 31936 (view as bug list)
Depends on:
Blocks:
 
Reported: 2007-03-15 16:51 UTC by Tobias Burnus
Modified: 2007-08-12 20:13 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2007-08-04 18:49:39


Attachments
Patch (943 bytes, patch)
2007-05-15 17:31 UTC, Tobias Burnus
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2007-03-15 16:51:44 UTC
Since PR 30498 is fixed, gfortran supports backtraces. However, they are only displayed for library errors not for, e.g., SEGV or signalling IEEE signals.

A support for these can be found embedded in the patch at
http://gcc.gnu.org/ml/gcc-patches/2007-02/msg00747.html
Comment 1 Francois-Xavier Coudert 2007-03-17 11:36:17 UTC
Confirmed. We have to be careful how that interacts with user-installed signal handlers, but it's otherwise a good idea.
Comment 2 Tobias Burnus 2007-05-15 15:17:05 UTC
*** Bug 31936 has been marked as a duplicate of this bug. ***
Comment 3 Tobias Burnus 2007-05-15 17:31:40 UTC
Created attachment 13558 [details]
Patch

> Since PR 30498 is fixed, gfortran supports backtraces. However, they are only
> displayed for library errors not for, e.g., SEGV or signalling IEEE signals.
> 
> A support for these can be found embedded in the patch at
> http://gcc.gnu.org/ml/gcc-patches/2007-02/msg00747.html

I extracted the non-committed parts of that patch.

> Confirmed. We have to be careful how that interacts with user-installed signal
> handlers, but it's otherwise a good idea.

I think this should be no problem. They are set very early before any user command has been set. If a user uses signal, he can install a user handler instead which overwrites the handler in libgfortran, which is probably what the user wants.

This covers: SIGSEGV, SIGILL, SIGFPE and SIGBUS

Examples:
a) uninitialized integer pointer:  integer, pointer :: i; i = 5
  Program received signal SIGILL: Segmentation fault
  Backtrace for this error:
    + /lib64/libc.so.6 [0x2af232dbf410]
    + function _fini (0x40084B)
b) Division by zero with -ffpe-trap=zero
  Program received signal SIGFPE: Segmentation fault
  Backtrace for this error:
    + /lib64/libc.so.6 [0x2b20b66d3410]
    + in the main program
      at line 5 of file x.f90
    + /lib64/libc.so.6(__libc_start_main+0xf4) [0x2b20b66c0944]

For (a) the backtrace using gdb is similarly useless.
Comment 4 Francois-Xavier Coudert 2007-08-04 18:49:39 UTC
Thanks Tobias for the patch, here's an updated version that I intend to submit for review...

Index: runtime/backtrace.c
===================================================================
--- runtime/backtrace.c (revision 127184)
+++ runtime/backtrace.c (working copy)
@@ -223,7 +223,8 @@ show_backtrace (void)
            /* Try to recognize the internal libgfortran functions.  */
            if (strncasecmp (func, "*_gfortran", 10) == 0
                || strncasecmp (func, "_gfortran", 9) == 0
-               || strcmp (func, "main") == 0 || strcmp (func, "_start") == 0)
+               || strcmp (func, "main") == 0 || strcmp (func, "_start") == 0
+               || strcmp (func, "_gfortrani_handler") == 0)
              continue;
 
            if (local_strcasestr (str[i], "libgfortran.so") != NULL
Index: libgfortran.h
===================================================================
--- libgfortran.h       (revision 127184)
+++ libgfortran.h       (working copy)
@@ -373,6 +373,9 @@ options_t;
 extern options_t options;
 internal_proto(options);
 
+extern void handler (int);
+internal_proto(handler);
+
 
 /* Compile-time options that will influence the library.  */
 
Index: runtime/compile_options.c
===================================================================
--- runtime/compile_options.c   (revision 127184)
+++ runtime/compile_options.c   (working copy)
@@ -31,10 +31,61 @@ Boston, MA 02110-1301, USA.  */
 
 #include "libgfortran.h"
 
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
 
 /* Useful compile-time options will be stored in here.  */
 compile_options_t compile_options;
 
+
+/* A signal handler to allow us to output a backtrace.  */
+void
+handler (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);
+
+  sys_exit (5);
+}
+
+
 /* Set the usual compile-time options.  */
 extern void set_options (int , int []);
 export_proto(set_options);
@@ -56,6 +107,31 @@ set_options (int num, int options[])
     compile_options.sign_zero = options[5];
   if (num >= 7)
     compile_options.bounds_check = options[6];
+
+  /* If backtrace is required, we set signal handlers on most common
+     signals.  */
+#if defined(HAVE_SIGNAL_H) && (defined(SIGSEGV) || defined(SIGBUS) \
+                              || defined(SIGILL) || defined(SIGFPE))
+  if (compile_options.backtrace)
+    {
+#if defined(SIGSEGV)
+      signal (SIGSEGV, handler);
+#endif
+
+#if defined(SIGBUS)
+      signal (SIGBUS, handler);
+#endif
+
+#if defined(SIGILL)
+      signal (SIGILL, handler);
+#endif
+
+#if defined(SIGFPE)
+      signal (SIGFPE, handler);
+#endif
+    }
+#endif
+
 }
 
 
Comment 5 Francois-Xavier Coudert 2007-08-11 21:52:34 UTC
Subject: Bug 31189

Author: fxcoudert
Date: Sat Aug 11 21:52:22 2007
New Revision: 127364

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=127364
Log:
	PR fortran/31189

	* runtime/backtrace.c (show_backtrace): Skip _gfortrani_handler
	when displaying backtrace.
	* runtime/compile_options.c: Include <signal.h>.
	(handler): New function.
	(set_options): Set signal handlers for backtrace.
	* libgfortran.h (handler): Add prototype.

	* invoke.texi (-fbacktrace): Document the new behaviour.

Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/invoke.texi
    trunk/libgfortran/ChangeLog
    trunk/libgfortran/libgfortran.h
    trunk/libgfortran/runtime/backtrace.c
    trunk/libgfortran/runtime/compile_options.c

Comment 6 Francois-Xavier Coudert 2007-08-12 20:13:07 UTC
Fixed, thanks Tobias for the first version of the patch.