From 71cda9cac819730fa340ebd83ec7f4bc9fd5d399 Mon Sep 17 00:00:00 2001 From: Janne Blomqvist Date: Sat, 5 Sep 2015 01:17:11 +0300 Subject: [PATCH] PR 53379 Print backtrace on error termination. 2015-09-05 Janne Blomqvist PR fortran/53379 * libgfortran.h (exit_error): New prototype. * runtime/error.c (exit_error): New function. (os_error): Call exit_error instead of exit. (runtime_error): Likewise. (runtime_error_at): Likewise. (internal_error): Likewise. (generate_error): Likewise. (notify_std): Likewise. * runtime/stop.c (error_stop_string): Likewise. (error_stop_numeric): Likewise. From-SVN: r227503 --- libgfortran/ChangeLog | 14 +++++++++++ libgfortran/libgfortran.h | 3 +++ libgfortran/runtime/error.c | 49 +++++++++++++++++++++++++------------ libgfortran/runtime/stop.c | 4 +-- 4 files changed, 53 insertions(+), 17 deletions(-) diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 5da6ea32fd6..8b4c27cbc95 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,17 @@ +2015-09-05 Janne Blomqvist + + PR fortran/53379 + * libgfortran.h (exit_error): New prototype. + * runtime/error.c (exit_error): New function. + (os_error): Call exit_error instead of exit. + (runtime_error): Likewise. + (runtime_error_at): Likewise. + (internal_error): Likewise. + (generate_error): Likewise. + (notify_std): Likewise. + * runtime/stop.c (error_stop_string): Likewise. + (error_stop_numeric): Likewise. + 2015-09-04 Janne Blomqvist * io/unix.h (delete_file): Remove prototype. diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h index 3eb0d85fa24..81240e591b8 100644 --- a/libgfortran/libgfortran.h +++ b/libgfortran/libgfortran.h @@ -675,6 +675,9 @@ internal_proto(show_backtrace); extern _Noreturn void sys_abort (void); internal_proto(sys_abort); +extern _Noreturn void exit_error (int); +internal_proto(exit_error); + extern ssize_t estr_write (const char *); internal_proto(estr_write); diff --git a/libgfortran/runtime/error.c b/libgfortran/runtime/error.c index 4aabe4a4a74..d357edb460d 100644 --- a/libgfortran/runtime/error.c +++ b/libgfortran/runtime/error.c @@ -74,15 +74,17 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 2.3.5 also explains how co-images synchronize during termination. - In libgfortran we have two ways of ending a program. exit(code) is - a normal exit; calling exit() also causes open units to be - closed. No backtrace or core dump is needed here. When something - goes wrong, we have sys_abort() which tries to print the backtrace - if -fbacktrace is enabled, and then dumps core; whether a core file - is generated is system dependent. When aborting, we don't flush and - close open units, as program memory might be corrupted and we'd - rather risk losing dirty data in the buffers rather than corrupting - files on disk. + In libgfortran we have three ways of ending a program. exit(code) + is a normal exit; calling exit() also causes open units to be + closed. No backtrace or core dump is needed here. For error + termination, we have exit_error(status), which prints a backtrace + if backtracing is enabled, then exits. Finally, when something + goes terribly wrong, we have sys_abort() which tries to print the + backtrace if -fbacktrace is enabled, and then dumps core; whether a + core file is generated is system dependent. When aborting, we don't + flush and close open units, as program memory might be corrupted + and we'd rather risk losing dirty data in the buffers rather than + corrupting files on disk. */ @@ -181,6 +183,23 @@ sys_abort (void) } +/* Exit in case of error termination. If backtracing is enabled, print + backtrace, then exit. */ + +void +exit_error (int status) +{ + if (options.backtrace == 1 + || (options.backtrace == -1 && compile_options.backtrace == 1)) + { + estr_write ("\nError termination. Backtrace:\n"); + show_backtrace (false); + } + exit (status); +} + + + /* gfc_xtoa()-- Integer to hexadecimal conversion. */ const char * @@ -326,7 +345,7 @@ os_error (const char *message) estr_write ("\n"); estr_write (message); estr_write ("\n"); - exit (1); + exit_error (1); } iexport(os_error); @@ -345,7 +364,7 @@ runtime_error (const char *message, ...) st_vprintf (message, ap); va_end (ap); estr_write ("\n"); - exit (2); + exit_error (2); } iexport(runtime_error); @@ -364,7 +383,7 @@ runtime_error_at (const char *where, const char *message, ...) st_vprintf (message, ap); va_end (ap); estr_write ("\n"); - exit (2); + exit_error (2); } iexport(runtime_error_at); @@ -402,7 +421,7 @@ internal_error (st_parameter_common *cmp, const char *message) because hopefully it doesn't happen too often). */ stupid_function_name_for_static_linking(); - exit (3); + exit_error (3); } @@ -574,7 +593,7 @@ generate_error (st_parameter_common *cmp, int family, const char *message) estr_write ("Fortran runtime error: "); estr_write (message); estr_write ("\n"); - exit (2); + exit_error (2); } iexport(generate_error); @@ -636,7 +655,7 @@ notify_std (st_parameter_common *cmp, int std, const char * message) estr_write ("Fortran runtime error: "); estr_write (message); estr_write ("\n"); - exit (2); + exit_error (2); } else { diff --git a/libgfortran/runtime/stop.c b/libgfortran/runtime/stop.c index 5c5483bd530..8b8a41f7274 100644 --- a/libgfortran/runtime/stop.c +++ b/libgfortran/runtime/stop.c @@ -145,7 +145,7 @@ error_stop_string (const char *string, GFC_INTEGER_4 len) (void) write (STDERR_FILENO, string, len); estr_write ("\n"); - exit (1); + exit_error (1); } @@ -159,5 +159,5 @@ error_stop_numeric (GFC_INTEGER_4 code) { report_exception (); st_printf ("ERROR STOP %d\n", (int) code); - exit (code); + exit_error (code); } -- 2.30.2