aboutsummaryrefslogtreecommitdiff
path: root/libgfortran/runtime/backtrace.c
diff options
context:
space:
mode:
authorJanne Blomqvist <jb@gcc.gnu.org>2015-09-02 17:51:40 +0300
committerJanne Blomqvist <jb@gcc.gnu.org>2015-09-02 17:51:40 +0300
commit1b0b9fcb928042bf30fb2e42247912d226f85513 (patch)
tree10abb98957304dbdbbb310cad62b7d3c654bb167 /libgfortran/runtime/backtrace.c
parent710465235b06be5b74b7fda1c8e2092b43d83e01 (diff)
downloadgcc-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.c40
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);
}