PR 48915 Abort handling

From-SVN: r173750
This commit is contained in:
Janne Blomqvist 2011-05-14 11:44:09 +03:00
parent 1028b2bded
commit de8bd1420e
16 changed files with 201 additions and 164 deletions

View File

@ -1,3 +1,18 @@
2011-05-14 Janne Blomqvist <jb@gcc.gnu.org>
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 <jb@gcc.gnu.org>
* gfortran.texi: Remove GFORTRAN_USE_STDERR documentation.

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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.
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.
@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.
@end table
@xref{Debugging Options,,Options for Debugging Your Program or GCC,

View File

@ -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

View File

@ -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;

View File

@ -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));

View File

@ -1,3 +1,39 @@
2011-05-14 Janne Blomqvist <jb@gcc.gnu.org>
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 <jb@gcc.gnu.org>
* io/unix.c (st_vprintf,st_printf): Move to runtime/error.c.

View File

@ -30,6 +30,5 @@ export_proto_np(PREFIX(abort));
void PREFIX(abort) (void)
{
close_units ();
abort ();
sys_abort ();
}

View File

@ -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);

View File

@ -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");
}

View File

@ -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;
/* 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;
switch (signum)
{
#if defined(SIGSEGV)
case SIGSEGV:
name = "SIGSEGV";
desc = "Segmentation fault";
break;
#endif
show_backtrace();
#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);
/* 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(SIGSEGV)
signal (SIGSEGV, handler);
#endif
#if defined(SIGBUS)
signal (SIGBUS, handler);
#if defined(SIGQUIT)
signal (SIGQUIT, backtrace_handler);
#endif
#if defined(SIGILL)
signal (SIGILL, handler);
signal (SIGILL, backtrace_handler);
#endif
#if defined(SIGABRT)
signal (SIGABRT, backtrace_handler);
#endif
#if defined(SIGFPE)
signal (SIGFPE, handler);
signal (SIGFPE, backtrace_handler);
#endif
#if defined(SIGSEGV)
signal (SIGSEGV, backtrace_handler);
#endif
#if defined(SIGBUS)
signal (SIGBUS, backtrace_handler);
#endif
#if defined(SIGSYS)
signal (SIGSYS, backtrace_handler);
#endif
#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;

View File

@ -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.

View File

@ -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. */
/* 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.
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 ();
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=.
/* 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. */
2.3.5 also explains how co-images synchronize during termination.
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);
}
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
{

View File

@ -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);
}