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
Confirmed. We have to be careful how that interacts with user-installed signal handlers, but it's otherwise a good idea.
*** Bug 31936 has been marked as a duplicate of this bug. ***
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.
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 + }
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
Fixed, thanks Tobias for the first version of the patch.