From c7987dcf7ddaf3cf116ada582cbe7efc561b58ef Mon Sep 17 00:00:00 2001 From: fxcoudert Date: Sat, 11 Aug 2007 21:52:22 +0000 Subject: [PATCH] PR fortran/31189 * runtime/backtrace.c (show_backtrace): Skip _gfortrani_handler when displaying backtrace. * runtime/compile_options.c: Include . (handler): New function. (set_options): Set signal handlers for backtrace. * libgfortran.h (handler): Add prototype. * invoke.texi (-fbacktrace): Document the new behaviour. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@127364 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/fortran/ChangeLog | 5 +++ gcc/fortran/invoke.texi | 4 +- libgfortran/ChangeLog | 11 +++++ libgfortran/libgfortran.h | 3 ++ libgfortran/runtime/backtrace.c | 3 +- libgfortran/runtime/compile_options.c | 76 +++++++++++++++++++++++++++++++++++ 6 files changed, 100 insertions(+), 2 deletions(-) diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 758ed43..cbd28a5 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,5 +1,10 @@ 2007-08-11 Francois-Xavier Coudert + PR fortran/31189 + * invoke.texi (-fbacktrace): Document the new behaviour. + +2007-08-11 Francois-Xavier Coudert + PR fortran/32937 * trans-array.c (gfc_conv_expr_descriptor): Use gfc_conv_const_charlen to generate backend_decl of right type. diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi index af90b58..b1d790a 100644 --- a/gcc/fortran/invoke.texi +++ b/gcc/fortran/invoke.texi @@ -544,7 +544,9 @@ zero), @samp{overflow} (overflow in a floating point operation), @opindex @code{fbacktrace} @cindex backtrace @cindex trace -Specify that, when a runtime error is encountered, the Fortran runtime +Specify that, when a runtime error is encountered or a deadly signal is +emitted (segmentation fault, illegal instruction, bus error or +floating-point exception), the Fortran runtime library should output a backtrace of the error. This option only has influence for compilation of the Fortran main program. diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 4e47f28..13c6f28 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,4 +1,15 @@ 2007-08-11 Francois-Xavier Coudert + Tobias Burnus + + PR fortran/31189 + * runtime/backtrace.c (show_backtrace): Skip _gfortrani_handler + when displaying backtrace. + * runtime/compile_options.c: Include . + (handler): New function. + (set_options): Set signal handlers for backtrace. + * libgfortran.h (handler): Add prototype. + +2007-08-11 Francois-Xavier Coudert * intrinsics/string_intrinsics.c (compare_string): Return an int. * libgfortran.h (compare_string): Likewise. diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h index 6013ce6..0671801 100644 --- a/libgfortran/libgfortran.h +++ b/libgfortran/libgfortran.h @@ -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. */ diff --git a/libgfortran/runtime/backtrace.c b/libgfortran/runtime/backtrace.c index 684ac00..e969341 100644 --- a/libgfortran/runtime/backtrace.c +++ b/libgfortran/runtime/backtrace.c @@ -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 diff --git a/libgfortran/runtime/compile_options.c b/libgfortran/runtime/compile_options.c index a6e2a42..c05b400 100644 --- a/libgfortran/runtime/compile_options.c +++ b/libgfortran/runtime/compile_options.c @@ -31,10 +31,61 @@ Boston, MA 02110-1301, USA. */ #include "libgfortran.h" +#ifdef HAVE_SIGNAL_H +#include +#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 + } -- 2.7.4