diff options
author | Janne Blomqvist <jb@gcc.gnu.org> | 2015-09-02 17:51:40 +0300 |
---|---|---|
committer | Janne Blomqvist <jb@gcc.gnu.org> | 2015-09-02 17:51:40 +0300 |
commit | 1b0b9fcb928042bf30fb2e42247912d226f85513 (patch) | |
tree | 10abb98957304dbdbbb310cad62b7d3c654bb167 /libgfortran/runtime/backtrace.c | |
parent | 710465235b06be5b74b7fda1c8e2092b43d83e01 (diff) | |
download | gcc-1b0b9fcb928042bf30fb2e42247912d226f85513.zip gcc-1b0b9fcb928042bf30fb2e42247912d226f85513.tar.gz gcc-1b0b9fcb928042bf30fb2e42247912d226f85513.tar.bz2 |
PR 67414 Better diagnostics on backtrace failure, gf_strerror bugfix
2015-09-02 Janne Blomqvist <jb@gcc.gnu.org>
PR libfortran/67414
* io/write.c (gfc_itoa): Move to runtime/string.c.
* libgfortran.h (show_backtrace): Make arg bool.
(gfc_itoa): New prototype.
* runtime/backtrace.c (struct mystate): Change type of try_simple
field, add in_signal_handler field.
(error_callback): Print out error number, or if not in a signal
handler, the error message.
(show_backtrace): Change type of arg, change initialization of
struct mystate.
(backtrace): Call show_backtrace with correct arg type.
* runtime/compile_options.c (backtrace_handler): Call with correct
arg type.
* runtime/error.c (sys_abort): Likewise.
(gf_strerror): Handle newlocale() failure.
* runtime/string.c (gfc_itoa): Function moved here from
io/write.c.
From-SVN: r227404
Diffstat (limited to 'libgfortran/runtime/backtrace.c')
-rw-r--r-- | libgfortran/runtime/backtrace.c | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/libgfortran/runtime/backtrace.c b/libgfortran/runtime/backtrace.c index 0d7c1fc..12ad76a 100644 --- a/libgfortran/runtime/backtrace.c +++ b/libgfortran/runtime/backtrace.c @@ -26,6 +26,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #include <string.h> #include <stdlib.h> +#include <errno.h> #ifdef HAVE_UNISTD_H #include <unistd.h> @@ -38,8 +39,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see /* Store our own state while backtracing. */ struct mystate { - int try_simple; int frame; + bool try_simple; + bool in_signal_handler; }; @@ -65,15 +67,35 @@ static void error_callback (void *data, const char *msg, int errnum) { struct mystate *state = (struct mystate *) data; +#define ERRHDR "\nCould not print backtrace: " + if (errnum < 0) { - state->try_simple = 1; + state->try_simple = true; return; } - - estr_write ("\nSomething went wrong while printing the backtrace: "); - estr_write (msg); - estr_write ("\n"); + else if (errnum == 0) + { + estr_write (ERRHDR); + estr_write (msg); + estr_write ("\n"); + } + else + { + char errbuf[256]; + if (state->in_signal_handler) + { + estr_write (ERRHDR); + estr_write (msg); + estr_write (", errno: "); + const char *p = gfc_itoa (errnum, errbuf, sizeof (errbuf)); + estr_write (p); + estr_write ("\n"); + } + else + st_printf (ERRHDR "%s: %s\n", msg, + gf_strerror (errnum, errbuf, sizeof (errbuf))); + } } static int @@ -110,10 +132,10 @@ full_callback (void *data, uintptr_t pc, const char *filename, /* Display the backtrace. */ void -show_backtrace (int in_signal_handler) +show_backtrace (bool in_signal_handler) { struct backtrace_state *lbstate; - struct mystate state = { 0, 0 }; + struct mystate state = { 0, false, in_signal_handler }; lbstate = backtrace_create_state (NULL, 1, error_callback, NULL); @@ -147,6 +169,6 @@ export_proto (backtrace); void backtrace (void) { - show_backtrace (0); + show_backtrace (false); } |