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:
parent
4805fc5533
commit
2437fd32f1
|
@ -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.
|
||||||
|
|
48
gdb/utils.c
48
gdb/utils.c
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue