PR 53379 Print backtrace on error termination.

2015-09-05  Janne Blomqvist  <jb@gcc.gnu.org>

	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
This commit is contained in:
Janne Blomqvist 2015-09-05 01:17:11 +03:00
parent 5e229618cd
commit 71cda9cac8
4 changed files with 53 additions and 17 deletions

View File

@ -1,3 +1,17 @@
2015-09-05 Janne Blomqvist <jb@gcc.gnu.org>
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 <jb@gcc.gnu.org> 2015-09-04 Janne Blomqvist <jb@gcc.gnu.org>
* io/unix.h (delete_file): Remove prototype. * io/unix.h (delete_file): Remove prototype.

View File

@ -675,6 +675,9 @@ internal_proto(show_backtrace);
extern _Noreturn void sys_abort (void); extern _Noreturn void sys_abort (void);
internal_proto(sys_abort); internal_proto(sys_abort);
extern _Noreturn void exit_error (int);
internal_proto(exit_error);
extern ssize_t estr_write (const char *); extern ssize_t estr_write (const char *);
internal_proto(estr_write); internal_proto(estr_write);

View File

@ -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. 2.3.5 also explains how co-images synchronize during termination.
In libgfortran we have two ways of ending a program. exit(code) is In libgfortran we have three ways of ending a program. exit(code)
a normal exit; calling exit() also causes open units to be is a normal exit; calling exit() also causes open units to be
closed. No backtrace or core dump is needed here. When something closed. No backtrace or core dump is needed here. For error
goes wrong, we have sys_abort() which tries to print the backtrace termination, we have exit_error(status), which prints a backtrace
if -fbacktrace is enabled, and then dumps core; whether a core file if backtracing is enabled, then exits. Finally, when something
is generated is system dependent. When aborting, we don't flush and goes terribly wrong, we have sys_abort() which tries to print the
close open units, as program memory might be corrupted and we'd backtrace if -fbacktrace is enabled, and then dumps core; whether a
rather risk losing dirty data in the buffers rather than corrupting core file is generated is system dependent. When aborting, we don't
files on disk. 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. */ /* gfc_xtoa()-- Integer to hexadecimal conversion. */
const char * const char *
@ -326,7 +345,7 @@ os_error (const char *message)
estr_write ("\n"); estr_write ("\n");
estr_write (message); estr_write (message);
estr_write ("\n"); estr_write ("\n");
exit (1); exit_error (1);
} }
iexport(os_error); iexport(os_error);
@ -345,7 +364,7 @@ runtime_error (const char *message, ...)
st_vprintf (message, ap); st_vprintf (message, ap);
va_end (ap); va_end (ap);
estr_write ("\n"); estr_write ("\n");
exit (2); exit_error (2);
} }
iexport(runtime_error); iexport(runtime_error);
@ -364,7 +383,7 @@ runtime_error_at (const char *where, const char *message, ...)
st_vprintf (message, ap); st_vprintf (message, ap);
va_end (ap); va_end (ap);
estr_write ("\n"); estr_write ("\n");
exit (2); exit_error (2);
} }
iexport(runtime_error_at); 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). */ because hopefully it doesn't happen too often). */
stupid_function_name_for_static_linking(); 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 ("Fortran runtime error: ");
estr_write (message); estr_write (message);
estr_write ("\n"); estr_write ("\n");
exit (2); exit_error (2);
} }
iexport(generate_error); 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 ("Fortran runtime error: ");
estr_write (message); estr_write (message);
estr_write ("\n"); estr_write ("\n");
exit (2); exit_error (2);
} }
else else
{ {

View File

@ -145,7 +145,7 @@ error_stop_string (const char *string, GFC_INTEGER_4 len)
(void) write (STDERR_FILENO, string, len); (void) write (STDERR_FILENO, string, len);
estr_write ("\n"); estr_write ("\n");
exit (1); exit_error (1);
} }
@ -159,5 +159,5 @@ error_stop_numeric (GFC_INTEGER_4 code)
{ {
report_exception (); report_exception ();
st_printf ("ERROR STOP %d\n", (int) code); st_printf ("ERROR STOP %d\n", (int) code);
exit (code); exit_error (code);
} }