From: Janne Blomqvist Date: Sat, 14 May 2011 08:44:09 +0000 (+0300) Subject: PR 48915 Abort handling X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=de8bd1420e94a63faef64c2ccac021fd89a11497;p=gcc.git PR 48915 Abort handling From-SVN: r173750 --- diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 4be4e5db4f4..afc553384ad 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,18 @@ +2011-05-14 Janne Blomqvist + + PR libfortran/48915 + * gfortran.h (gfc_option_t): Remove flag_dump_core. + * gfortran.texi (GFORTRAN_ERROR_DUMPCORE): Remove section. + (GFORTRAN_ERROR_BACKTRACE): Document that it's enabled by default. + * intrinsic.texi (ABORT): Remove explanation of -fdump-core. + * invoke.texi: Remove -fdump-core, document that -fbacktrace is + enabled by default. + * lang.opt: Remove -fdump-core. + * options.c (gfc_init_options): Make backtrace default to enabled, + remove dump_core. + (gfc_handle_option): Remove OPT_fdump-core. + * trans-decl.c: Pass a 0 to preserve ABI. + 2011-05-14 Janne Blomqvist * gfortran.texi: Remove GFORTRAN_USE_STDERR documentation. diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 92adf72e8af..3b4967de63a 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -2212,7 +2212,6 @@ typedef struct int flag_backslash; int flag_backtrace; int flag_allow_leading_underscore; - int flag_dump_core; int flag_external_blas; int blas_matmul_limit; int flag_cray_pointer; diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi index c810fe251d6..518c998793e 100644 --- a/gcc/fortran/gfortran.texi +++ b/gcc/fortran/gfortran.texi @@ -587,7 +587,6 @@ Malformed environment variables are silently ignored. * GFORTRAN_DEFAULT_RECL:: Default record length for new files * GFORTRAN_LIST_SEPARATOR:: Separator for list output * GFORTRAN_CONVERT_UNIT:: Set endianness for unformatted I/O -* GFORTRAN_ERROR_DUMPCORE:: Dump core on run-time errors * GFORTRAN_ERROR_BACKTRACE:: Show backtrace on run-time errors @end menu @@ -745,26 +744,15 @@ environment variable will override the CONVERT specifier in the open statement}. This is to give control over data formats to users who do not have the source code of their program available. -@node GFORTRAN_ERROR_DUMPCORE -@section @env{GFORTRAN_ERROR_DUMPCORE}---Dump core on run-time errors - -If the @env{GFORTRAN_ERROR_DUMPCORE} variable is set to -@samp{y}, @samp{Y} or @samp{1} (only the first letter is relevant) -then library run-time errors cause core dumps. To disable the core -dumps, set the variable to @samp{n}, @samp{N}, @samp{0}. Default -is not to core dump unless the @option{-fdump-core} compile option -was used. - @node GFORTRAN_ERROR_BACKTRACE @section @env{GFORTRAN_ERROR_BACKTRACE}---Show backtrace on run-time errors -If the @env{GFORTRAN_ERROR_BACKTRACE} variable is set to -@samp{y}, @samp{Y} or @samp{1} (only the first letter is relevant) -then a backtrace is printed when a run-time error occurs. -To disable the backtracing, set the variable to -@samp{n}, @samp{N}, @samp{0}. Default is not to print a backtrace -unless the @option{-fbacktrace} compile option -was used. +If the @env{GFORTRAN_ERROR_BACKTRACE} variable is set to @samp{y}, +@samp{Y} or @samp{1} (only the first letter is relevant) then a +backtrace is printed when a serious run-time error occurs. To disable +the backtracing, set the variable to @samp{n}, @samp{N}, @samp{0}. +Default is to print a backtrace unless the @option{-fno-backtrace} +compile option was used. @c ===================================================================== @c PART II: LANGUAGE REFERENCE diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi index ebffb1233a3..804b31f8f49 100644 --- a/gcc/fortran/intrinsic.texi +++ b/gcc/fortran/intrinsic.texi @@ -345,10 +345,7 @@ the applicable standard for each intrinsic procedure is noted. @table @asis @item @emph{Description}: @code{ABORT} causes immediate termination of the program. On operating -systems that support a core dump, @code{ABORT} will produce a core dump even if -the option @option{-fno-dump-core} is in effect, which is suitable for debugging -purposes. -@c TODO: Check if this (with -fno-dump-core) is correct. +systems that support a core dump, @code{ABORT} will produce a core dump. @item @emph{Standard}: GNU extension diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi index 9f022390b56..f68b18c6776 100644 --- a/gcc/fortran/invoke.texi +++ b/gcc/fortran/invoke.texi @@ -145,7 +145,7 @@ and warnings}. @item Debugging Options @xref{Debugging Options,,Options for debugging your program or GNU Fortran}. @gccoptlist{-fdump-fortran-original -fdump-fortran-optimized @gol --ffpe-trap=@var{list} -fdump-core -fbacktrace -fdump-parse-tree} +-ffpe-trap=@var{list} -fbacktrace -fdump-parse-tree} @item Directory Options @xref{Directory Options,,Options for directory search}. @@ -935,22 +935,18 @@ Some of the routines in the Fortran runtime library, like @code{ffpe-trap=precision} is used. For this reason, the use of @code{ffpe-trap=precision} is not recommended. -@item -fbacktrace -@opindex @code{fbacktrace} +@item -fno-backtrace +@opindex @code{fno-backtrace} @cindex backtrace @cindex trace -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. - -@item -fdump-core -@cindex core, dump -@opindex @code{fdump-core} -Request that a core-dump file is written to disk when a runtime error -is encountered on systems that support core dumps. This option is -only effective for the compilation of the Fortran main program. +When a serious runtime error is encountered or a deadly signal is +emitted (segmentation fault, illegal instruction, bus error, +floating-point exception, and the other POSIX signals that have the +action @samp{core}), the Fortran runtime library tries to output a +backtrace of the error. @code{-fno-backtrace} disables the backtrace +generation. This option only has influence for compilation of the +Fortran main program. + @end table @xref{Debugging Options,,Options for Debugging Your Program or GCC, diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt index ce944e3b4ce..a056c5c651e 100644 --- a/gcc/fortran/lang.opt +++ b/gcc/fortran/lang.opt @@ -366,10 +366,6 @@ fdollar-ok Fortran Allow dollar signs in entity names -fdump-core -Fortran -Dump a core file when a runtime error occurs - fdump-fortran-original Fortran Display the code tree after parsing diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c index c67d10916e9..d4778ba7b1e 100644 --- a/gcc/fortran/options.c +++ b/gcc/fortran/options.c @@ -134,9 +134,8 @@ gfc_init_options (unsigned int decoded_options_count, gfc_option.flag_automatic = 1; gfc_option.flag_backslash = 0; gfc_option.flag_module_private = 0; - gfc_option.flag_backtrace = 0; + gfc_option.flag_backtrace = 1; gfc_option.flag_allow_leading_underscore = 0; - gfc_option.flag_dump_core = 0; gfc_option.flag_external_blas = 0; gfc_option.blas_matmul_limit = 30; gfc_option.flag_cray_pointer = 0; @@ -697,10 +696,6 @@ gfc_handle_option (size_t scode, const char *arg, int value, gfc_option.rtcheck |= GFC_RTCHECK_ARRAY_TEMPS; break; - case OPT_fdump_core: - gfc_option.flag_dump_core = value; - break; - case OPT_fcray_pointer: gfc_option.flag_cray_pointer = value; break; diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index 77e2a594ee2..f0138b0076c 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -4636,9 +4636,12 @@ create_main_function (tree fndecl) gfc_option.allow_std)); CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, pedantic)); + /* TODO: This is the old -fdump-core option, which is unused but + passed due to ABI compatibility; remove when bumping the + library ABI. */ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, - gfc_option.flag_dump_core)); + 0)); CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, gfc_option.flag_backtrace)); diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 8ed0bb6148f..ada4eae6ef5 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,39 @@ +2011-05-14 Janne Blomqvist + + PR libfortran/48915 + * intrinsics/abort.c (abort): Call sys_abort(). + * io/unix.c (st_vprintf): Call sys_abort(). + * libgfortran.h (options_t): Remove dump_core member. + (handler): Rename to backtrace_handler. + (compile_options_t): Remove dump_core member. + (sys_exit): Remove. + (sys_abort): New function. + * runtime/backtrace.c (show_backtrace): Print a message if + backtrace is not available on target, update filter symbol name + due to backtrace_handler renaming. + * runtime/compile_options.c (backtrace_handler): New + implementation based on example in Glibc manual. + (set_options): Remove dump_core handling, make signal handler + handle more signals. + (init_compile_options): Remove dump_core. + * runtime/environ.c (variable_table[]): Remove + GFORTRAN_ERROR_DUMPCORE element. + (show_variables): Update name, call exit(). + * runtime/error.c (sys_exit): Remove. + (sys_abort): New function. + (recursion_check): Call sys_abort(). + (os_error): Call exit(). + (runtime_error): Likewise. + (runtime_error_at): Likewise. + (internal_error): Likewise. + (generate_error): Likewise. + (notify_std): Likewise. + * runtime/stop.c (stop_numeric): Call exit(). + (stop_numeric_f08): Likewise. + (stop_string): Likewise. + (error_stop_string): Call sys_abort(). + (error_stop_numeric): Print backtrace, exit with provided code. + 2011-05-14 Janne Blomqvist * io/unix.c (st_vprintf,st_printf): Move to runtime/error.c. diff --git a/libgfortran/intrinsics/abort.c b/libgfortran/intrinsics/abort.c index ada40614365..543f8fc04c8 100644 --- a/libgfortran/intrinsics/abort.c +++ b/libgfortran/intrinsics/abort.c @@ -30,6 +30,5 @@ export_proto_np(PREFIX(abort)); void PREFIX(abort) (void) { - close_units (); - abort (); + sys_abort (); } diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h index ae86a021ee3..e77ba10790f 100644 --- a/libgfortran/libgfortran.h +++ b/libgfortran/libgfortran.h @@ -509,15 +509,15 @@ typedef struct const char *separator; int all_unbuffered, unbuffered_preconnected, default_recl; - int fpe, dump_core, backtrace; + int fpe, backtrace; } options_t; extern options_t options; internal_proto(options); -extern void handler (int); -internal_proto(handler); +extern void backtrace_handler (int); +internal_proto(backtrace_handler); /* Compile-time options that will influence the library. */ @@ -528,7 +528,6 @@ typedef struct int allow_std; int pedantic; int convert; - int dump_core; int backtrace; int sign_zero; size_t record_marker; @@ -688,8 +687,8 @@ internal_proto(show_backtrace); #define GFC_OTOA_BUF_SIZE (GFC_LARGEST_BUF * 3 + 1) #define GFC_BTOA_BUF_SIZE (GFC_LARGEST_BUF * 8 + 1) -extern void sys_exit (int) __attribute__ ((noreturn)); -internal_proto(sys_exit); +extern void sys_abort (void) __attribute__ ((noreturn)); +internal_proto(sys_abort); extern ssize_t estr_write (const char *); internal_proto(estr_write); diff --git a/libgfortran/runtime/backtrace.c b/libgfortran/runtime/backtrace.c index aa77025ab74..10917d3e0c2 100644 --- a/libgfortran/runtime/backtrace.c +++ b/libgfortran/runtime/backtrace.c @@ -214,7 +214,7 @@ show_backtrace (void) if (strncasecmp (func, "*_gfortran", 10) == 0 || strncasecmp (func, "_gfortran", 9) == 0 || strcmp (func, "main") == 0 || strcmp (func, "_start") == 0 - || strcmp (func, "_gfortrani_handler") == 0) + || strcmp (func, "_gfortrani_backtrace_handler") == 0) continue; if (local_strcasestr (str[i], "libgfortran.so") != NULL @@ -334,5 +334,7 @@ fallback: /* Fallback to the glibc backtrace. */ estr_write ("\nBacktrace for this error:\n"); dump_glibc_backtrace (depth, str); + return; #endif + estr_write ("\nBacktrace not yet available on this platform, sorry!\n"); } diff --git a/libgfortran/runtime/compile_options.c b/libgfortran/runtime/compile_options.c index 62c401be6b3..dc0da4bcb90 100644 --- a/libgfortran/runtime/compile_options.c +++ b/libgfortran/runtime/compile_options.c @@ -33,49 +33,28 @@ 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; + /* A signal handler to allow us to output a backtrace. */ void -handler (int signum) +backtrace_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); + /* Since this handler is established for more than one kind of signal, + it might still get invoked recursively by delivery of some other kind + of signal. Use a static variable to keep track of that. */ + if (fatal_error_in_progress) + raise (signum); + fatal_error_in_progress = 1; + + 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, + but reraising the signal sets the return status + from the process correctly. */ + signal (signum, SIG_DFL); + raise (signum); } @@ -92,8 +71,9 @@ set_options (int num, int options[]) compile_options.allow_std = options[1]; if (num >= 3) compile_options.pedantic = options[2]; - if (num >= 4) - compile_options.dump_core = options[3]; + /* options[3] is the removed -fdump-core option. It's place in the + options array is retained due to ABI compatibility. Remove when + bumping the library ABI. */ if (num >= 5) compile_options.backtrace = options[4]; if (num >= 6) @@ -103,26 +83,53 @@ set_options (int num, int options[]) if (num >= 8) compile_options.range_check = options[7]; - /* If backtrace is required, we set signal handlers on most common - signals. */ -#if defined(HAVE_SIGNAL) && (defined(SIGSEGV) || defined(SIGBUS) \ - || defined(SIGILL) || defined(SIGFPE)) + /* If backtrace is required, we set signal handlers on the POSIX + 2001 signals with core action. */ +#if defined(HAVE_SIGNAL) && (defined(SIGQUIT) || defined(SIGILL) \ + || defined(SIGABRT) || defined(SIGFPE) \ + || defined(SIGSEGV) || defined(SIGBUS) \ + || defined(SIGSYS) || defined(SIGTRAP) \ + || defined(SIGXCPU) || defined(SIGXFSZ)) if (compile_options.backtrace) { +#if defined(SIGQUIT) + signal (SIGQUIT, backtrace_handler); +#endif + +#if defined(SIGILL) + signal (SIGILL, backtrace_handler); +#endif + +#if defined(SIGABRT) + signal (SIGABRT, backtrace_handler); +#endif + +#if defined(SIGFPE) + signal (SIGFPE, backtrace_handler); +#endif + #if defined(SIGSEGV) - signal (SIGSEGV, handler); + signal (SIGSEGV, backtrace_handler); #endif #if defined(SIGBUS) - signal (SIGBUS, handler); + signal (SIGBUS, backtrace_handler); #endif -#if defined(SIGILL) - signal (SIGILL, handler); +#if defined(SIGSYS) + signal (SIGSYS, backtrace_handler); #endif -#if defined(SIGFPE) - signal (SIGFPE, handler); +#if defined(SIGTRAP) + signal (SIGTRAP, backtrace_handler); +#endif + +#if defined(SIGXCPU) + signal (SIGXCPU, backtrace_handler); +#endif + +#if defined(SIGXFSZ) + signal (SIGXFSZ, backtrace_handler); #endif } #endif @@ -140,7 +147,6 @@ init_compile_options (void) | GFC_STD_F2003 | GFC_STD_F2008 | GFC_STD_F95 | GFC_STD_F77 | GFC_STD_F2008_OBS | GFC_STD_GNU | GFC_STD_LEGACY; compile_options.pedantic = 0; - compile_options.dump_core = 0; compile_options.backtrace = 0; compile_options.sign_zero = 1; compile_options.range_check = 1; diff --git a/libgfortran/runtime/environ.c b/libgfortran/runtime/environ.c index 7695f0db198..6bd88865d89 100644 --- a/libgfortran/runtime/environ.c +++ b/libgfortran/runtime/environ.c @@ -318,11 +318,6 @@ static variable variable_table[] = { {"GFORTRAN_CONVERT_UNIT", 0, 0, init_unformatted, show_string, "Set format for unformatted files", 0}, - /* Behaviour when encoutering a runtime error. */ - {"GFORTRAN_ERROR_DUMPCORE", -1, &options.dump_core, - init_boolean, show_boolean, - "Dump a core file (if possible) on runtime error", -1}, - {"GFORTRAN_ERROR_BACKTRACE", -1, &options.backtrace, init_boolean, show_boolean, "Print out a backtrace (if possible) on runtime error", -1}, @@ -388,7 +383,7 @@ show_variables (void) estr_write ("\nCommand line arguments:\n"); estr_write (" --help Print this list\n"); - sys_exit (0); + exit (0); } /* This is the handling of the GFORTRAN_CONVERT_UNITS environment variable. diff --git a/libgfortran/runtime/error.c b/libgfortran/runtime/error.c index e61904496c8..dae298df203 100644 --- a/libgfortran/runtime/error.c +++ b/libgfortran/runtime/error.c @@ -58,44 +58,32 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #endif -/* sys_exit()-- Terminate the program with an exit code. */ - -void -sys_exit (int code) -{ - /* Show error backtrace if possible. */ - if (code != 0 && code != 4 - && (options.backtrace == 1 - || (options.backtrace == -1 && compile_options.backtrace == 1))) - show_backtrace (); - - /* Dump core if requested. */ - if (code != 0 - && (options.dump_core == 1 - || (options.dump_core == -1 && compile_options.dump_core == 1))) - { -#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE) - /* Warn if a core file cannot be produced because - of core size limit. */ - - struct rlimit core_limit; - - if (getrlimit (RLIMIT_CORE, &core_limit) == 0 && core_limit.rlim_cur == 0) - estr_write ("** Warning: a core dump was requested, but the core size" - "limit\n** is currently zero.\n\n"); -#endif - - -#if defined(HAVE_KILL) && defined(HAVE_GETPID) && defined(SIGQUIT) - kill (getpid (), SIGQUIT); -#else - estr_write ("Core dump not possible, sorry."); -#endif - } - - exit (code); -} - +/* Termination of a program: F2008 2.3.5 talks about "normal + termination" and "error termination". Normal termination occurs as + a result of e.g. executing the end program statement, and executing + the STOP statement. It includes the effect of the C exit() + function. + + Error termination is initiated when the ERROR STOP statement is + executed, when ALLOCATE/DEALLOCATE fails without STAT= being + specified, when some of the co-array synchronization statements + fail without STAT= being specified, and some I/O errors if + ERR/IOSTAT/END/EOR is not present, and finally EXECUTE_COMMAND_LINE + failure without CMDSTAT=. + + 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. + +*/ /* Error conditions. The tricky part here is printing a message when * it is the I/O subsystem that is severely wounded. Our goal is to @@ -107,7 +95,6 @@ sys_exit (int code) * 1 Terminated because of operating system error. * 2 Error in the runtime library * 3 Internal error in runtime library - * 4 Error during error processing (very bad) * * Other error returns are reserved for the STOP statement with a numeric code. */ @@ -150,7 +137,7 @@ st_vprintf (const char *format, va_list ap) #define ERROR_MESSAGE "Internal error: buffer overrun in st_vprintf()\n" write (STDERR_FILENO, buffer, ST_VPRINTF_SIZE - 1); write (STDERR_FILENO, ERROR_MESSAGE, strlen(ERROR_MESSAGE)); - sys_exit(2); + sys_abort (); #undef ERROR_MESSAGE } @@ -173,6 +160,27 @@ st_printf (const char * format, ...) } +/* sys_abort()-- Terminate the program showing backtrace and dumping + core. */ + +void +sys_abort () +{ + /* If backtracing is enabled, print backtrace and disable signal + handler for ABRT. */ + if (options.backtrace == 1 + || (options.backtrace == -1 && compile_options.backtrace == 1)) + { + show_backtrace (); +#if defined(HAVE_SIGNAL) && defined(SIGABRT) + signal (SIGABRT, SIG_DFL); +#endif + } + + abort(); +} + + /* gfc_xtoa()-- Integer to hexadecimal conversion. */ const char * @@ -278,7 +286,7 @@ recursion_check (void) /* Don't even try to print something at this point */ if (magic == MAGIC) - sys_exit (4); + sys_abort (); magic = MAGIC; } @@ -300,7 +308,7 @@ os_error (const char *message) estr_write ("\n"); estr_write (message); estr_write ("\n"); - sys_exit (1); + exit (1); } iexport(os_error); @@ -319,7 +327,7 @@ runtime_error (const char *message, ...) st_vprintf (message, ap); va_end (ap); estr_write ("\n"); - sys_exit (2); + exit (2); } iexport(runtime_error); @@ -338,7 +346,7 @@ runtime_error_at (const char *where, const char *message, ...) st_vprintf (message, ap); va_end (ap); estr_write ("\n"); - sys_exit (2); + exit (2); } iexport(runtime_error_at); @@ -376,7 +384,7 @@ internal_error (st_parameter_common *cmp, const char *message) because hopefully it doesn't happen too often). */ stupid_function_name_for_static_linking(); - sys_exit (3); + exit (3); } @@ -544,7 +552,7 @@ generate_error (st_parameter_common *cmp, int family, const char *message) estr_write ("Fortran runtime error: "); estr_write (message); estr_write ("\n"); - sys_exit (2); + exit (2); } iexport(generate_error); @@ -606,7 +614,7 @@ notify_std (st_parameter_common *cmp, int std, const char * message) estr_write ("Fortran runtime error: "); estr_write (message); estr_write ("\n"); - sys_exit (2); + exit (2); } else { diff --git a/libgfortran/runtime/stop.c b/libgfortran/runtime/stop.c index b6f61ff8bee..2efe23924e7 100644 --- a/libgfortran/runtime/stop.c +++ b/libgfortran/runtime/stop.c @@ -41,7 +41,7 @@ stop_numeric (GFC_INTEGER_4 code) else st_printf ("STOP %d\n", (int)code); - sys_exit (code); + exit (code); } @@ -55,7 +55,7 @@ void stop_numeric_f08 (GFC_INTEGER_4 code) { st_printf ("STOP %d\n", (int)code); - sys_exit (code); + exit (code); } @@ -71,7 +71,7 @@ stop_string (const char *string, GFC_INTEGER_4 len) (void) sizeof (w); /* Avoid compiler warning about not using w. */ estr_write ("\n"); } - sys_exit (0); + exit (0); } @@ -92,7 +92,7 @@ error_stop_string (const char *string, GFC_INTEGER_4 len) (void) sizeof (w); /* Avoid compiler warning about not using w. */ estr_write ("\n"); - sys_exit (1); + sys_abort (); } @@ -106,5 +106,8 @@ void error_stop_numeric (GFC_INTEGER_4 code) { st_printf ("ERROR STOP %d\n", (int) code); - sys_exit (code); + if (options.backtrace == 1 + || (options.backtrace == -1 && compile_options.backtrace == 1)) + show_backtrace (); + exit (code); }