diff options
author | Gary Benson <gbenson@redhat.com> | 2014-08-05 11:42:21 +0100 |
---|---|---|
committer | Gary Benson <gbenson@redhat.com> | 2014-08-29 10:11:59 +0100 |
commit | 2437fd32f17cb11338949cff1fd0741e14ce1681 (patch) | |
tree | 2bcf8bd5e476b038acf8db7cad7772fc949f298d | |
parent | 4805fc5533c158766d04f58af62bea884d624421 (diff) | |
download | gdb-2437fd32f17cb11338949cff1fd0741e14ce1681.zip gdb-2437fd32f17cb11338949cff1fd0741e14ce1681.tar.gz gdb-2437fd32f17cb11338949cff1fd0741e14ce1681.tar.bz2 |
Make internal_vproblem always work
internal_vproblem can be called (via malloc_failure) from almost the
first line of captured_main, but it will crash if called before the
first call to set_width. This commit makes internal_vproblem work
at any time.
There are two parts to this. If called before gdb_stderr is set up,
internal_vproblem will fall back to printing the message on regular
stderr and aborting. If called after gdb_stderr is set up but before
filtered printing is set up, internal_vproblem will operate as usual
except that it can not query whether to quit and/or dump core so it
defaults to doing both.
gdb/ChangeLog:
* utils.h (filtered_printing_initialized): New declaration.
* utils.c (abort_with_message): New function.
(internal_vproblem): Use abort_with_message for first level
recursive internal problems, and if gdb_stderr is not set up.
Protect calls to target_terminal_ours, begin_line and query.
-rw-r--r-- | gdb/ChangeLog | 8 | ||||
-rw-r--r-- | gdb/utils.c | 48 | ||||
-rw-r--r-- | gdb/utils.h | 3 |
3 files changed, 51 insertions, 8 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 1da3063..1a086ca 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2014-08-29 Gary Benson <gbenson@redhat.com> + + * utils.h (filtered_printing_initialized): New declaration. + * utils.c (abort_with_message): New function. + (internal_vproblem): Use abort_with_message for first level + recursive internal problems, and if gdb_stderr is not set up. + Protect calls to target_terminal_ours, begin_line and query. + 2014-08-28 Doug Evans <dje@google.com> * symtab.c (in_prologue): Move definition to better spot. diff --git a/gdb/utils.c b/gdb/utils.c index 4984373..5fe9ee6 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -549,6 +549,19 @@ error_stream (struct ui_file *stream) error (("%s"), message); } +/* Emit a message and abort. */ + +static void ATTRIBUTE_NORETURN +abort_with_message (const char *msg) +{ + if (gdb_stderr == NULL) + fputs (msg, stderr); + else + fputs_unfiltered (msg, gdb_stderr); + + abort (); /* NOTE: GDB has only three calls to abort(). */ +} + /* Dump core trying to increase the core soft limit to hard limit first. */ void @@ -671,8 +684,7 @@ internal_vproblem (struct internal_problem *problem, break; case 1: dejavu = 2; - fputs_unfiltered (msg, gdb_stderr); - abort (); /* NOTE: GDB has only three calls to abort(). */ + abort_with_message (msg); default: dejavu = 3; /* Newer GLIBC versions put the warn_unused_result attribute @@ -686,10 +698,6 @@ internal_vproblem (struct internal_problem *problem, } } - /* Try to get the message out and at the start of a new line. */ - target_terminal_ours (); - begin_line (); - /* Create a string containing the full error/warning message. Need to call query with this full string, as otherwize the reason (error/warning) and question become separated. Format using a @@ -707,8 +715,23 @@ internal_vproblem (struct internal_problem *problem, make_cleanup (xfree, reason); } + /* Fall back to abort_with_message if gdb_stderr is not set up. */ + if (gdb_stderr == NULL) + { + fputs (reason, stderr); + abort_with_message ("\n"); + } + + /* Try to get the message out and at the start of a new line. */ + if (target_supports_terminal_ours ()) + target_terminal_ours (); + if (filtered_printing_initialized ()) + begin_line (); + /* Emit the message unless query will emit it below. */ - if (problem->should_quit != internal_problem_ask || !confirm) + if (problem->should_quit != internal_problem_ask + || !confirm + || !filtered_printing_initialized ()) fprintf_unfiltered (gdb_stderr, "%s\n", reason); if (problem->should_quit == internal_problem_ask) @@ -716,7 +739,7 @@ internal_vproblem (struct internal_problem *problem, /* Default (yes/batch case) is to quit GDB. When in batch mode this lessens the likelihood of GDB going into an infinite loop. */ - if (!confirm) + if (!confirm || !filtered_printing_initialized ()) quit_p = 1; else quit_p = query (_("%s\nQuit this debugging session? "), reason); @@ -738,6 +761,8 @@ internal_vproblem (struct internal_problem *problem, { if (!can_dump_core_warn (LIMIT_MAX, reason)) dump_core_p = 0; + else if (!filtered_printing_initialized ()) + dump_core_p = 1; else { /* Default (yes/batch case) is to dump core. This leaves a GDB @@ -1700,6 +1725,13 @@ init_page_info (void) set_width (); } +/* Return nonzero if filtered printing is initialized. */ +int +filtered_printing_initialized (void) +{ + return wrap_buffer != NULL; +} + /* Helper for make_cleanup_restore_page_info. */ static void diff --git a/gdb/utils.h b/gdb/utils.h index 57a1c0f..62888a7 100644 --- a/gdb/utils.h +++ b/gdb/utils.h @@ -244,6 +244,9 @@ extern void fputstrn_filtered (const char *str, int n, int quotr, extern void fputstrn_unfiltered (const char *str, int n, int quotr, struct ui_file * stream); +/* Return nonzero if filtered printing is initialized. */ +extern int filtered_printing_initialized (void); + /* Display the host ADDR on STREAM formatted as ``0x%x''. */ extern void gdb_print_host_address (const void *addr, struct ui_file *stream); |