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.
This commit is contained in:
Gary Benson 2014-08-05 11:42:21 +01:00
parent 4805fc5533
commit 2437fd32f1
3 changed files with 51 additions and 8 deletions

View File

@ -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> 2014-08-28 Doug Evans <dje@google.com>
* symtab.c (in_prologue): Move definition to better spot. * symtab.c (in_prologue): Move definition to better spot.

View File

@ -549,6 +549,19 @@ error_stream (struct ui_file *stream)
error (("%s"), message); 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. */ /* Dump core trying to increase the core soft limit to hard limit first. */
void void
@ -671,8 +684,7 @@ internal_vproblem (struct internal_problem *problem,
break; break;
case 1: case 1:
dejavu = 2; dejavu = 2;
fputs_unfiltered (msg, gdb_stderr); abort_with_message (msg);
abort (); /* NOTE: GDB has only three calls to abort(). */
default: default:
dejavu = 3; dejavu = 3;
/* Newer GLIBC versions put the warn_unused_result attribute /* 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 /* Create a string containing the full error/warning message. Need
to call query with this full string, as otherwize the reason to call query with this full string, as otherwize the reason
(error/warning) and question become separated. Format using a (error/warning) and question become separated. Format using a
@ -707,8 +715,23 @@ internal_vproblem (struct internal_problem *problem,
make_cleanup (xfree, reason); 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. */ /* 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); fprintf_unfiltered (gdb_stderr, "%s\n", reason);
if (problem->should_quit == internal_problem_ask) 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 /* Default (yes/batch case) is to quit GDB. When in batch mode
this lessens the likelihood of GDB going into an infinite this lessens the likelihood of GDB going into an infinite
loop. */ loop. */
if (!confirm) if (!confirm || !filtered_printing_initialized ())
quit_p = 1; quit_p = 1;
else else
quit_p = query (_("%s\nQuit this debugging session? "), reason); 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)) if (!can_dump_core_warn (LIMIT_MAX, reason))
dump_core_p = 0; dump_core_p = 0;
else if (!filtered_printing_initialized ())
dump_core_p = 1;
else else
{ {
/* Default (yes/batch case) is to dump core. This leaves a GDB /* Default (yes/batch case) is to dump core. This leaves a GDB
@ -1700,6 +1725,13 @@ init_page_info (void)
set_width (); 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. */ /* Helper for make_cleanup_restore_page_info. */
static void static void

View File

@ -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, extern void fputstrn_unfiltered (const char *str, int n, int quotr,
struct ui_file * stream); 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''. */ /* Display the host ADDR on STREAM formatted as ``0x%x''. */
extern void gdb_print_host_address (const void *addr, struct ui_file *stream); extern void gdb_print_host_address (const void *addr, struct ui_file *stream);