PR gdb/11327, PR gdb/11328, PR breakpoints/11368:
* infrun.c (handle_inferior_event): Change initialization of stop_stack_dummy. (handle_inferior_event): Change assignment to stop_stack_dummy. (normal_stop): Update use of stop_stack_dummy. (struct inferior_status) <stop_stack_dummy>: Change type. * inferior.h (stop_stack_dummy): Update. * infcmd.c (stop_stack_dummy): Change type. * infcall.c (cleanup_delete_std_terminate_breakpoint): New function. (call_function_by_hand): Call set_std_terminate_breakpoint. Rewrite std::terminate handling. * breakpoint.h (enum bptype) <bp_std_terminate, bp_std_terminate_master>: New. (enum stop_stack_kind): New. (struct bpstat_what) <call_dummy>: Change type. (set_std_terminate_breakpoint, delete_std_terminate_breakpoint): Declare. * breakpoint.c (create_std_terminate_master_breakpoint): New function. (update_breakpoints_after_exec): Handle bp_std_terminate_master. Call create_std_terminate_master_breakpoint. (print_it_typical): Handle new breakpoint kinds. (bpstat_stop_status): Handle bp_std_terminate_master. (bpstat_what): Correctly set call_dummy field. Handle bp_std_terminate_master and bp_std_terminate. (print_one_breakpoint_location): Update. (allocate_bp_location): Update. (set_std_terminate_breakpoint): New function. (delete_std_terminate_breakpoint): Likewise. (create_thread_event_breakpoint): Update. (delete_command): Update. (breakpoint_re_set_one): Update. (breakpoint_re_set): Call create_std_terminate_master_breakpoint.
This commit is contained in:
parent
82ccf5a577
commit
aa7d318d60
7 changed files with 191 additions and 52 deletions
|
@ -1,3 +1,40 @@
|
||||||
|
2010-03-25 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
|
PR gdb/11327, PR gdb/11328, PR breakpoints/11368:
|
||||||
|
* infrun.c (handle_inferior_event): Change initialization of
|
||||||
|
stop_stack_dummy.
|
||||||
|
(handle_inferior_event): Change assignment to stop_stack_dummy.
|
||||||
|
(normal_stop): Update use of stop_stack_dummy.
|
||||||
|
(struct inferior_status) <stop_stack_dummy>: Change type.
|
||||||
|
* inferior.h (stop_stack_dummy): Update.
|
||||||
|
* infcmd.c (stop_stack_dummy): Change type.
|
||||||
|
* infcall.c (cleanup_delete_std_terminate_breakpoint): New
|
||||||
|
function.
|
||||||
|
(call_function_by_hand): Call set_std_terminate_breakpoint.
|
||||||
|
Rewrite std::terminate handling.
|
||||||
|
* breakpoint.h (enum bptype) <bp_std_terminate,
|
||||||
|
bp_std_terminate_master>: New.
|
||||||
|
(enum stop_stack_kind): New.
|
||||||
|
(struct bpstat_what) <call_dummy>: Change type.
|
||||||
|
(set_std_terminate_breakpoint, delete_std_terminate_breakpoint):
|
||||||
|
Declare.
|
||||||
|
* breakpoint.c (create_std_terminate_master_breakpoint): New
|
||||||
|
function.
|
||||||
|
(update_breakpoints_after_exec): Handle bp_std_terminate_master.
|
||||||
|
Call create_std_terminate_master_breakpoint.
|
||||||
|
(print_it_typical): Handle new breakpoint kinds.
|
||||||
|
(bpstat_stop_status): Handle bp_std_terminate_master.
|
||||||
|
(bpstat_what): Correctly set call_dummy field. Handle
|
||||||
|
bp_std_terminate_master and bp_std_terminate.
|
||||||
|
(print_one_breakpoint_location): Update.
|
||||||
|
(allocate_bp_location): Update.
|
||||||
|
(set_std_terminate_breakpoint): New function.
|
||||||
|
(delete_std_terminate_breakpoint): Likewise.
|
||||||
|
(create_thread_event_breakpoint): Update.
|
||||||
|
(delete_command): Update.
|
||||||
|
(breakpoint_re_set_one): Update.
|
||||||
|
(breakpoint_re_set): Call create_std_terminate_master_breakpoint.
|
||||||
|
|
||||||
2010-03-25 Jan Kratochvil <jan.kratochvil@redhat.com>
|
2010-03-25 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
|
||||||
* symfile.c (build_section_addr_info_from_bfd): New.
|
* symfile.c (build_section_addr_info_from_bfd): New.
|
||||||
|
|
101
gdb/breakpoint.c
101
gdb/breakpoint.c
|
@ -2157,6 +2157,41 @@ create_longjmp_master_breakpoint (char *func_name)
|
||||||
do_cleanups (old_chain);
|
do_cleanups (old_chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create a master std::terminate breakpoint. The actual function
|
||||||
|
looked for is named FUNC_NAME. */
|
||||||
|
static void
|
||||||
|
create_std_terminate_master_breakpoint (const char *func_name)
|
||||||
|
{
|
||||||
|
struct program_space *pspace;
|
||||||
|
struct objfile *objfile;
|
||||||
|
struct cleanup *old_chain;
|
||||||
|
|
||||||
|
old_chain = save_current_program_space ();
|
||||||
|
|
||||||
|
ALL_PSPACES (pspace)
|
||||||
|
ALL_OBJFILES (objfile)
|
||||||
|
{
|
||||||
|
struct breakpoint *b;
|
||||||
|
struct minimal_symbol *m;
|
||||||
|
|
||||||
|
set_current_program_space (pspace);
|
||||||
|
|
||||||
|
m = lookup_minimal_symbol (func_name, NULL, objfile);
|
||||||
|
if (m == NULL || (MSYMBOL_TYPE (m) != mst_text
|
||||||
|
&& MSYMBOL_TYPE (m) != mst_file_text))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
b = create_internal_breakpoint (get_objfile_arch (objfile),
|
||||||
|
SYMBOL_VALUE_ADDRESS (m),
|
||||||
|
bp_std_terminate_master);
|
||||||
|
b->addr_string = xstrdup (func_name);
|
||||||
|
b->enable_state = bp_disabled;
|
||||||
|
}
|
||||||
|
update_global_location_list (1);
|
||||||
|
|
||||||
|
do_cleanups (old_chain);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
update_breakpoints_after_exec (void)
|
update_breakpoints_after_exec (void)
|
||||||
{
|
{
|
||||||
|
@ -2198,7 +2233,7 @@ update_breakpoints_after_exec (void)
|
||||||
/* Thread event breakpoints must be set anew after an exec(),
|
/* Thread event breakpoints must be set anew after an exec(),
|
||||||
as must overlay event and longjmp master breakpoints. */
|
as must overlay event and longjmp master breakpoints. */
|
||||||
if (b->type == bp_thread_event || b->type == bp_overlay_event
|
if (b->type == bp_thread_event || b->type == bp_overlay_event
|
||||||
|| b->type == bp_longjmp_master)
|
|| b->type == bp_longjmp_master || b->type == bp_std_terminate_master)
|
||||||
{
|
{
|
||||||
delete_breakpoint (b);
|
delete_breakpoint (b);
|
||||||
continue;
|
continue;
|
||||||
|
@ -2274,6 +2309,7 @@ update_breakpoints_after_exec (void)
|
||||||
create_longjmp_master_breakpoint ("_longjmp");
|
create_longjmp_master_breakpoint ("_longjmp");
|
||||||
create_longjmp_master_breakpoint ("siglongjmp");
|
create_longjmp_master_breakpoint ("siglongjmp");
|
||||||
create_longjmp_master_breakpoint ("_siglongjmp");
|
create_longjmp_master_breakpoint ("_siglongjmp");
|
||||||
|
create_std_terminate_master_breakpoint ("std::terminate()");
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -3202,6 +3238,12 @@ print_it_typical (bpstat bs)
|
||||||
result = PRINT_NOTHING;
|
result = PRINT_NOTHING;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case bp_std_terminate_master:
|
||||||
|
/* These should never be enabled. */
|
||||||
|
printf_filtered (_("std::terminate Master Breakpoint: gdb should not stop!\n"));
|
||||||
|
result = PRINT_NOTHING;
|
||||||
|
break;
|
||||||
|
|
||||||
case bp_watchpoint:
|
case bp_watchpoint:
|
||||||
case bp_hardware_watchpoint:
|
case bp_hardware_watchpoint:
|
||||||
annotate_watchpoint (b->number);
|
annotate_watchpoint (b->number);
|
||||||
|
@ -3292,6 +3334,7 @@ print_it_typical (bpstat bs)
|
||||||
case bp_step_resume:
|
case bp_step_resume:
|
||||||
case bp_watchpoint_scope:
|
case bp_watchpoint_scope:
|
||||||
case bp_call_dummy:
|
case bp_call_dummy:
|
||||||
|
case bp_std_terminate:
|
||||||
case bp_tracepoint:
|
case bp_tracepoint:
|
||||||
case bp_fast_tracepoint:
|
case bp_fast_tracepoint:
|
||||||
case bp_jit_event:
|
case bp_jit_event:
|
||||||
|
@ -4035,7 +4078,8 @@ bpstat_stop_status (struct address_space *aspace,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (b->type == bp_thread_event || b->type == bp_overlay_event
|
if (b->type == bp_thread_event || b->type == bp_overlay_event
|
||||||
|| b->type == bp_longjmp_master)
|
|| b->type == bp_longjmp_master
|
||||||
|
|| b->type == bp_std_terminate_master)
|
||||||
/* We do not stop for these. */
|
/* We do not stop for these. */
|
||||||
bs->stop = 0;
|
bs->stop = 0;
|
||||||
else
|
else
|
||||||
|
@ -4245,7 +4289,7 @@ bpstat_what (bpstat bs)
|
||||||
enum bpstat_what_main_action current_action = BPSTAT_WHAT_KEEP_CHECKING;
|
enum bpstat_what_main_action current_action = BPSTAT_WHAT_KEEP_CHECKING;
|
||||||
struct bpstat_what retval;
|
struct bpstat_what retval;
|
||||||
|
|
||||||
retval.call_dummy = 0;
|
retval.call_dummy = STOP_NONE;
|
||||||
for (; bs != NULL; bs = bs->next)
|
for (; bs != NULL; bs = bs->next)
|
||||||
{
|
{
|
||||||
enum class bs_class = no_effect;
|
enum class bs_class = no_effect;
|
||||||
|
@ -4318,6 +4362,7 @@ bpstat_what (bpstat bs)
|
||||||
case bp_thread_event:
|
case bp_thread_event:
|
||||||
case bp_overlay_event:
|
case bp_overlay_event:
|
||||||
case bp_longjmp_master:
|
case bp_longjmp_master:
|
||||||
|
case bp_std_terminate_master:
|
||||||
bs_class = bp_nostop;
|
bs_class = bp_nostop;
|
||||||
break;
|
break;
|
||||||
case bp_catchpoint:
|
case bp_catchpoint:
|
||||||
|
@ -4337,7 +4382,13 @@ bpstat_what (bpstat bs)
|
||||||
/* Make sure the action is stop (silent or noisy),
|
/* Make sure the action is stop (silent or noisy),
|
||||||
so infrun.c pops the dummy frame. */
|
so infrun.c pops the dummy frame. */
|
||||||
bs_class = bp_silent;
|
bs_class = bp_silent;
|
||||||
retval.call_dummy = 1;
|
retval.call_dummy = STOP_STACK_DUMMY;
|
||||||
|
break;
|
||||||
|
case bp_std_terminate:
|
||||||
|
/* Make sure the action is stop (silent or noisy),
|
||||||
|
so infrun.c pops the dummy frame. */
|
||||||
|
bs_class = bp_silent;
|
||||||
|
retval.call_dummy = STOP_STD_TERMINATE;
|
||||||
break;
|
break;
|
||||||
case bp_tracepoint:
|
case bp_tracepoint:
|
||||||
case bp_fast_tracepoint:
|
case bp_fast_tracepoint:
|
||||||
|
@ -4465,10 +4516,12 @@ print_one_breakpoint_location (struct breakpoint *b,
|
||||||
{bp_step_resume, "step resume"},
|
{bp_step_resume, "step resume"},
|
||||||
{bp_watchpoint_scope, "watchpoint scope"},
|
{bp_watchpoint_scope, "watchpoint scope"},
|
||||||
{bp_call_dummy, "call dummy"},
|
{bp_call_dummy, "call dummy"},
|
||||||
|
{bp_std_terminate, "std::terminate"},
|
||||||
{bp_shlib_event, "shlib events"},
|
{bp_shlib_event, "shlib events"},
|
||||||
{bp_thread_event, "thread events"},
|
{bp_thread_event, "thread events"},
|
||||||
{bp_overlay_event, "overlay events"},
|
{bp_overlay_event, "overlay events"},
|
||||||
{bp_longjmp_master, "longjmp master"},
|
{bp_longjmp_master, "longjmp master"},
|
||||||
|
{bp_std_terminate_master, "std::terminate master"},
|
||||||
{bp_catchpoint, "catchpoint"},
|
{bp_catchpoint, "catchpoint"},
|
||||||
{bp_tracepoint, "tracepoint"},
|
{bp_tracepoint, "tracepoint"},
|
||||||
{bp_fast_tracepoint, "fast tracepoint"},
|
{bp_fast_tracepoint, "fast tracepoint"},
|
||||||
|
@ -4596,10 +4649,12 @@ print_one_breakpoint_location (struct breakpoint *b,
|
||||||
case bp_step_resume:
|
case bp_step_resume:
|
||||||
case bp_watchpoint_scope:
|
case bp_watchpoint_scope:
|
||||||
case bp_call_dummy:
|
case bp_call_dummy:
|
||||||
|
case bp_std_terminate:
|
||||||
case bp_shlib_event:
|
case bp_shlib_event:
|
||||||
case bp_thread_event:
|
case bp_thread_event:
|
||||||
case bp_overlay_event:
|
case bp_overlay_event:
|
||||||
case bp_longjmp_master:
|
case bp_longjmp_master:
|
||||||
|
case bp_std_terminate_master:
|
||||||
case bp_tracepoint:
|
case bp_tracepoint:
|
||||||
case bp_fast_tracepoint:
|
case bp_fast_tracepoint:
|
||||||
case bp_jit_event:
|
case bp_jit_event:
|
||||||
|
@ -5235,11 +5290,13 @@ allocate_bp_location (struct breakpoint *bpt)
|
||||||
case bp_step_resume:
|
case bp_step_resume:
|
||||||
case bp_watchpoint_scope:
|
case bp_watchpoint_scope:
|
||||||
case bp_call_dummy:
|
case bp_call_dummy:
|
||||||
|
case bp_std_terminate:
|
||||||
case bp_shlib_event:
|
case bp_shlib_event:
|
||||||
case bp_thread_event:
|
case bp_thread_event:
|
||||||
case bp_overlay_event:
|
case bp_overlay_event:
|
||||||
case bp_jit_event:
|
case bp_jit_event:
|
||||||
case bp_longjmp_master:
|
case bp_longjmp_master:
|
||||||
|
case bp_std_terminate_master:
|
||||||
loc->loc_type = bp_loc_software_breakpoint;
|
loc->loc_type = bp_loc_software_breakpoint;
|
||||||
break;
|
break;
|
||||||
case bp_hardware_breakpoint:
|
case bp_hardware_breakpoint:
|
||||||
|
@ -5492,6 +5549,33 @@ disable_overlay_breakpoints (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set an active std::terminate breakpoint for each std::terminate
|
||||||
|
master breakpoint. */
|
||||||
|
void
|
||||||
|
set_std_terminate_breakpoint (void)
|
||||||
|
{
|
||||||
|
struct breakpoint *b, *temp;
|
||||||
|
|
||||||
|
ALL_BREAKPOINTS_SAFE (b, temp)
|
||||||
|
if (b->pspace == current_program_space
|
||||||
|
&& b->type == bp_std_terminate_master)
|
||||||
|
{
|
||||||
|
struct breakpoint *clone = clone_momentary_breakpoint (b);
|
||||||
|
clone->type = bp_std_terminate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delete all the std::terminate breakpoints. */
|
||||||
|
void
|
||||||
|
delete_std_terminate_breakpoint (void)
|
||||||
|
{
|
||||||
|
struct breakpoint *b, *temp;
|
||||||
|
|
||||||
|
ALL_BREAKPOINTS_SAFE (b, temp)
|
||||||
|
if (b->type == bp_std_terminate)
|
||||||
|
delete_breakpoint (b);
|
||||||
|
}
|
||||||
|
|
||||||
struct breakpoint *
|
struct breakpoint *
|
||||||
create_thread_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
|
create_thread_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
|
||||||
{
|
{
|
||||||
|
@ -6537,12 +6621,14 @@ mention (struct breakpoint *b)
|
||||||
case bp_longjmp_resume:
|
case bp_longjmp_resume:
|
||||||
case bp_step_resume:
|
case bp_step_resume:
|
||||||
case bp_call_dummy:
|
case bp_call_dummy:
|
||||||
|
case bp_std_terminate:
|
||||||
case bp_watchpoint_scope:
|
case bp_watchpoint_scope:
|
||||||
case bp_shlib_event:
|
case bp_shlib_event:
|
||||||
case bp_thread_event:
|
case bp_thread_event:
|
||||||
case bp_overlay_event:
|
case bp_overlay_event:
|
||||||
case bp_jit_event:
|
case bp_jit_event:
|
||||||
case bp_longjmp_master:
|
case bp_longjmp_master:
|
||||||
|
case bp_std_terminate_master:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9222,11 +9308,13 @@ delete_command (char *arg, int from_tty)
|
||||||
ALL_BREAKPOINTS (b)
|
ALL_BREAKPOINTS (b)
|
||||||
{
|
{
|
||||||
if (b->type != bp_call_dummy
|
if (b->type != bp_call_dummy
|
||||||
|
&& b->type != bp_std_terminate
|
||||||
&& b->type != bp_shlib_event
|
&& b->type != bp_shlib_event
|
||||||
&& b->type != bp_jit_event
|
&& b->type != bp_jit_event
|
||||||
&& b->type != bp_thread_event
|
&& b->type != bp_thread_event
|
||||||
&& b->type != bp_overlay_event
|
&& b->type != bp_overlay_event
|
||||||
&& b->type != bp_longjmp_master
|
&& b->type != bp_longjmp_master
|
||||||
|
&& b->type != bp_std_terminate_master
|
||||||
&& b->number >= 0)
|
&& b->number >= 0)
|
||||||
{
|
{
|
||||||
breaks_to_delete = 1;
|
breaks_to_delete = 1;
|
||||||
|
@ -9241,11 +9329,13 @@ delete_command (char *arg, int from_tty)
|
||||||
ALL_BREAKPOINTS_SAFE (b, temp)
|
ALL_BREAKPOINTS_SAFE (b, temp)
|
||||||
{
|
{
|
||||||
if (b->type != bp_call_dummy
|
if (b->type != bp_call_dummy
|
||||||
|
&& b->type != bp_std_terminate
|
||||||
&& b->type != bp_shlib_event
|
&& b->type != bp_shlib_event
|
||||||
&& b->type != bp_thread_event
|
&& b->type != bp_thread_event
|
||||||
&& b->type != bp_jit_event
|
&& b->type != bp_jit_event
|
||||||
&& b->type != bp_overlay_event
|
&& b->type != bp_overlay_event
|
||||||
&& b->type != bp_longjmp_master
|
&& b->type != bp_longjmp_master
|
||||||
|
&& b->type != bp_std_terminate_master
|
||||||
&& b->number >= 0)
|
&& b->number >= 0)
|
||||||
delete_breakpoint (b);
|
delete_breakpoint (b);
|
||||||
}
|
}
|
||||||
|
@ -9556,6 +9646,7 @@ breakpoint_re_set_one (void *bint)
|
||||||
reset later by breakpoint_re_set. */
|
reset later by breakpoint_re_set. */
|
||||||
case bp_overlay_event:
|
case bp_overlay_event:
|
||||||
case bp_longjmp_master:
|
case bp_longjmp_master:
|
||||||
|
case bp_std_terminate_master:
|
||||||
delete_breakpoint (b);
|
delete_breakpoint (b);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -9575,6 +9666,7 @@ breakpoint_re_set_one (void *bint)
|
||||||
case bp_finish:
|
case bp_finish:
|
||||||
case bp_watchpoint_scope:
|
case bp_watchpoint_scope:
|
||||||
case bp_call_dummy:
|
case bp_call_dummy:
|
||||||
|
case bp_std_terminate:
|
||||||
case bp_step_resume:
|
case bp_step_resume:
|
||||||
case bp_longjmp:
|
case bp_longjmp:
|
||||||
case bp_longjmp_resume:
|
case bp_longjmp_resume:
|
||||||
|
@ -9620,6 +9712,7 @@ breakpoint_re_set (void)
|
||||||
create_longjmp_master_breakpoint ("_longjmp");
|
create_longjmp_master_breakpoint ("_longjmp");
|
||||||
create_longjmp_master_breakpoint ("siglongjmp");
|
create_longjmp_master_breakpoint ("siglongjmp");
|
||||||
create_longjmp_master_breakpoint ("_siglongjmp");
|
create_longjmp_master_breakpoint ("_siglongjmp");
|
||||||
|
create_std_terminate_master_breakpoint ("std::terminate()");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset the thread number of this breakpoint:
|
/* Reset the thread number of this breakpoint:
|
||||||
|
|
|
@ -83,6 +83,10 @@ enum bptype
|
||||||
of scope (with hardware support for watchpoints)). */
|
of scope (with hardware support for watchpoints)). */
|
||||||
bp_call_dummy,
|
bp_call_dummy,
|
||||||
|
|
||||||
|
/* A breakpoint set on std::terminate, that is used to catch
|
||||||
|
otherwise uncaught exceptions thrown during an inferior call. */
|
||||||
|
bp_std_terminate,
|
||||||
|
|
||||||
/* Some dynamic linkers (HP, maybe Solaris) can arrange for special
|
/* Some dynamic linkers (HP, maybe Solaris) can arrange for special
|
||||||
code in the inferior to run when significant events occur in the
|
code in the inferior to run when significant events occur in the
|
||||||
dynamic linker (for example a library is loaded or unloaded).
|
dynamic linker (for example a library is loaded or unloaded).
|
||||||
|
@ -118,6 +122,9 @@ enum bptype
|
||||||
|
|
||||||
bp_longjmp_master,
|
bp_longjmp_master,
|
||||||
|
|
||||||
|
/* Master copies of std::terminate breakpoints. */
|
||||||
|
bp_std_terminate_master,
|
||||||
|
|
||||||
bp_catchpoint,
|
bp_catchpoint,
|
||||||
|
|
||||||
bp_tracepoint,
|
bp_tracepoint,
|
||||||
|
@ -609,6 +616,20 @@ enum bpstat_what_main_action
|
||||||
BPSTAT_WHAT_LAST
|
BPSTAT_WHAT_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* An enum indicating the kind of "stack dummy" stop. This is a bit
|
||||||
|
of a misnomer because only one kind of truly a stack dummy. */
|
||||||
|
enum stop_stack_kind
|
||||||
|
{
|
||||||
|
/* We didn't stop at a stack dummy breakpoint. */
|
||||||
|
STOP_NONE = 0,
|
||||||
|
|
||||||
|
/* Stopped at a stack dummy. */
|
||||||
|
STOP_STACK_DUMMY,
|
||||||
|
|
||||||
|
/* Stopped at std::terminate. */
|
||||||
|
STOP_STD_TERMINATE
|
||||||
|
};
|
||||||
|
|
||||||
struct bpstat_what
|
struct bpstat_what
|
||||||
{
|
{
|
||||||
enum bpstat_what_main_action main_action;
|
enum bpstat_what_main_action main_action;
|
||||||
|
@ -617,7 +638,7 @@ struct bpstat_what
|
||||||
of BPSTAT_WHAT_STOP_SILENT or BPSTAT_WHAT_STOP_NOISY (the concept of
|
of BPSTAT_WHAT_STOP_SILENT or BPSTAT_WHAT_STOP_NOISY (the concept of
|
||||||
continuing from a call dummy without popping the frame is not a
|
continuing from a call dummy without popping the frame is not a
|
||||||
useful one). */
|
useful one). */
|
||||||
int call_dummy;
|
enum stop_stack_kind call_dummy;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The possible return values for print_bpstat, print_it_normal,
|
/* The possible return values for print_bpstat, print_it_normal,
|
||||||
|
@ -865,6 +886,9 @@ extern void delete_longjmp_breakpoint (int thread);
|
||||||
extern void enable_overlay_breakpoints (void);
|
extern void enable_overlay_breakpoints (void);
|
||||||
extern void disable_overlay_breakpoints (void);
|
extern void disable_overlay_breakpoints (void);
|
||||||
|
|
||||||
|
extern void set_std_terminate_breakpoint (void);
|
||||||
|
extern void delete_std_terminate_breakpoint (void);
|
||||||
|
|
||||||
/* These functions respectively disable or reenable all currently
|
/* These functions respectively disable or reenable all currently
|
||||||
enabled watchpoints. When disabled, the watchpoints are marked
|
enabled watchpoints. When disabled, the watchpoints are marked
|
||||||
call_disabled. When reenabled, they are marked enabled.
|
call_disabled. When reenabled, they are marked enabled.
|
||||||
|
|
|
@ -403,6 +403,13 @@ run_inferior_call (struct thread_info *call_thread, CORE_ADDR real_pc)
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* A cleanup function that calls delete_std_terminate_breakpoint. */
|
||||||
|
static void
|
||||||
|
cleanup_delete_std_terminate_breakpoint (void *ignore)
|
||||||
|
{
|
||||||
|
delete_std_terminate_breakpoint ();
|
||||||
|
}
|
||||||
|
|
||||||
/* All this stuff with a dummy frame may seem unnecessarily complicated
|
/* All this stuff with a dummy frame may seem unnecessarily complicated
|
||||||
(why not just save registers in GDB?). The purpose of pushing a dummy
|
(why not just save registers in GDB?). The purpose of pushing a dummy
|
||||||
frame which looks just like a real frame is so that if you call a
|
frame which looks just like a real frame is so that if you call a
|
||||||
|
@ -440,9 +447,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
|
||||||
struct cleanup *args_cleanup;
|
struct cleanup *args_cleanup;
|
||||||
struct frame_info *frame;
|
struct frame_info *frame;
|
||||||
struct gdbarch *gdbarch;
|
struct gdbarch *gdbarch;
|
||||||
struct breakpoint *terminate_bp = NULL;
|
struct cleanup *terminate_bp_cleanup;
|
||||||
struct minimal_symbol *tm;
|
|
||||||
struct cleanup *terminate_bp_cleanup = NULL;
|
|
||||||
ptid_t call_thread_ptid;
|
ptid_t call_thread_ptid;
|
||||||
struct gdb_exception e;
|
struct gdb_exception e;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@ -757,13 +762,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
|
||||||
call. Place a momentary breakpoint in the std::terminate function
|
call. Place a momentary breakpoint in the std::terminate function
|
||||||
and if triggered in the call, rewind. */
|
and if triggered in the call, rewind. */
|
||||||
if (unwind_on_terminating_exception_p)
|
if (unwind_on_terminating_exception_p)
|
||||||
{
|
set_std_terminate_breakpoint ();
|
||||||
struct minimal_symbol *tm = lookup_minimal_symbol ("std::terminate()",
|
|
||||||
NULL, NULL);
|
|
||||||
if (tm != NULL)
|
|
||||||
terminate_bp = set_momentary_breakpoint_at_pc
|
|
||||||
(gdbarch, SYMBOL_VALUE_ADDRESS (tm), bp_breakpoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Everything's ready, push all the info needed to restore the
|
/* Everything's ready, push all the info needed to restore the
|
||||||
caller (and identify the dummy-frame) onto the dummy-frame
|
caller (and identify the dummy-frame) onto the dummy-frame
|
||||||
|
@ -776,8 +775,8 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
|
||||||
discard_cleanups (inf_status_cleanup);
|
discard_cleanups (inf_status_cleanup);
|
||||||
|
|
||||||
/* Register a clean-up for unwind_on_terminating_exception_breakpoint. */
|
/* Register a clean-up for unwind_on_terminating_exception_breakpoint. */
|
||||||
if (terminate_bp)
|
terminate_bp_cleanup = make_cleanup (cleanup_delete_std_terminate_breakpoint,
|
||||||
terminate_bp_cleanup = make_cleanup_delete_breakpoint (terminate_bp);
|
NULL);
|
||||||
|
|
||||||
/* - SNIP - SNIP - SNIP - SNIP - SNIP - SNIP - SNIP - SNIP - SNIP -
|
/* - SNIP - SNIP - SNIP - SNIP - SNIP - SNIP - SNIP - SNIP - SNIP -
|
||||||
If you're looking to implement asynchronous dummy-frames, then
|
If you're looking to implement asynchronous dummy-frames, then
|
||||||
|
@ -878,7 +877,7 @@ When the function is done executing, GDB will silently stop."),
|
||||||
name);
|
name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stopped_by_random_signal || !stop_stack_dummy)
|
if (stopped_by_random_signal || stop_stack_dummy != STOP_STACK_DUMMY)
|
||||||
{
|
{
|
||||||
const char *name = get_function_name (funaddr,
|
const char *name = get_function_name (funaddr,
|
||||||
name_buf, sizeof (name_buf));
|
name_buf, sizeof (name_buf));
|
||||||
|
@ -932,30 +931,17 @@ When the function is done executing, GDB will silently stop."),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!stop_stack_dummy)
|
if (stop_stack_dummy == STOP_STD_TERMINATE)
|
||||||
{
|
{
|
||||||
|
/* We must get back to the frame we were before the dummy
|
||||||
|
call. */
|
||||||
|
dummy_frame_pop (dummy_id);
|
||||||
|
|
||||||
/* Check if unwind on terminating exception behaviour is on. */
|
/* We also need to restore inferior status to that before
|
||||||
if (unwind_on_terminating_exception_p)
|
the dummy call. */
|
||||||
{
|
restore_inferior_status (inf_status);
|
||||||
/* Check that the breakpoint is our special std::terminate
|
|
||||||
breakpoint. If it is, we do not want to kill the inferior
|
|
||||||
in an inferior function call. Rewind, and warn the
|
|
||||||
user. */
|
|
||||||
|
|
||||||
if (terminate_bp != NULL
|
error (_("\
|
||||||
&& (inferior_thread ()->stop_bpstat->breakpoint_at->address
|
|
||||||
== terminate_bp->loc->address))
|
|
||||||
{
|
|
||||||
/* We must get back to the frame we were before the
|
|
||||||
dummy call. */
|
|
||||||
dummy_frame_pop (dummy_id);
|
|
||||||
|
|
||||||
/* We also need to restore inferior status to that before the
|
|
||||||
dummy call. */
|
|
||||||
restore_inferior_status (inf_status);
|
|
||||||
|
|
||||||
error (_("\
|
|
||||||
The program being debugged entered a std::terminate call, most likely\n\
|
The program being debugged entered a std::terminate call, most likely\n\
|
||||||
caused by an unhandled C++ exception. GDB blocked this call in order\n\
|
caused by an unhandled C++ exception. GDB blocked this call in order\n\
|
||||||
to prevent the program from being terminated, and has restored the\n\
|
to prevent the program from being terminated, and has restored the\n\
|
||||||
|
@ -963,9 +949,11 @@ context to its original state before the call.\n\
|
||||||
To change this behaviour use \"set unwind-on-terminating-exception off\".\n\
|
To change this behaviour use \"set unwind-on-terminating-exception off\".\n\
|
||||||
Evaluation of the expression containing the function (%s)\n\
|
Evaluation of the expression containing the function (%s)\n\
|
||||||
will be abandoned."),
|
will be abandoned."),
|
||||||
name);
|
name);
|
||||||
}
|
}
|
||||||
}
|
else if (stop_stack_dummy == STOP_NONE)
|
||||||
|
{
|
||||||
|
|
||||||
/* We hit a breakpoint inside the FUNCTION.
|
/* We hit a breakpoint inside the FUNCTION.
|
||||||
Keep the dummy frame, the user may want to examine its state.
|
Keep the dummy frame, the user may want to examine its state.
|
||||||
Discard inferior status, we're not at the same point
|
Discard inferior status, we're not at the same point
|
||||||
|
@ -992,10 +980,7 @@ When the function is done executing, GDB will silently stop."),
|
||||||
internal_error (__FILE__, __LINE__, _("... should not be here"));
|
internal_error (__FILE__, __LINE__, _("... should not be here"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we get here and the std::terminate() breakpoint has been set,
|
do_cleanups (terminate_bp_cleanup);
|
||||||
it has to be cleaned manually. */
|
|
||||||
if (terminate_bp)
|
|
||||||
do_cleanups (terminate_bp_cleanup);
|
|
||||||
|
|
||||||
/* If we get here the called FUNCTION ran to completion,
|
/* If we get here the called FUNCTION ran to completion,
|
||||||
and the dummy frame has already been popped. */
|
and the dummy frame has already been popped. */
|
||||||
|
|
|
@ -155,7 +155,7 @@ int breakpoint_proceeded;
|
||||||
|
|
||||||
/* Nonzero if stopped due to completion of a stack dummy routine. */
|
/* Nonzero if stopped due to completion of a stack dummy routine. */
|
||||||
|
|
||||||
int stop_stack_dummy;
|
enum stop_stack_kind stop_stack_dummy;
|
||||||
|
|
||||||
/* Nonzero if stopped due to a random (unexpected) signal in inferior
|
/* Nonzero if stopped due to a random (unexpected) signal in inferior
|
||||||
process. */
|
process. */
|
||||||
|
|
|
@ -297,7 +297,7 @@ extern CORE_ADDR stop_pc;
|
||||||
|
|
||||||
/* Nonzero if stopped due to completion of a stack dummy routine. */
|
/* Nonzero if stopped due to completion of a stack dummy routine. */
|
||||||
|
|
||||||
extern int stop_stack_dummy;
|
extern enum stop_stack_kind stop_stack_dummy;
|
||||||
|
|
||||||
/* Nonzero if program stopped due to a random (unexpected) signal in
|
/* Nonzero if program stopped due to a random (unexpected) signal in
|
||||||
inferior process. */
|
inferior process. */
|
||||||
|
|
|
@ -2904,7 +2904,7 @@ handle_inferior_event (struct execution_control_state *ecs)
|
||||||
target_last_waitstatus = ecs->ws;
|
target_last_waitstatus = ecs->ws;
|
||||||
|
|
||||||
/* Always clear state belonging to the previous time we stopped. */
|
/* Always clear state belonging to the previous time we stopped. */
|
||||||
stop_stack_dummy = 0;
|
stop_stack_dummy = STOP_NONE;
|
||||||
|
|
||||||
/* If it's a new process, add it to the thread database */
|
/* If it's a new process, add it to the thread database */
|
||||||
|
|
||||||
|
@ -3970,7 +3970,7 @@ process_event_stop_test:
|
||||||
|
|
||||||
if (what.call_dummy)
|
if (what.call_dummy)
|
||||||
{
|
{
|
||||||
stop_stack_dummy = 1;
|
stop_stack_dummy = what.call_dummy;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (what.main_action)
|
switch (what.main_action)
|
||||||
|
@ -5460,7 +5460,7 @@ Further execution is probably impossible.\n"));
|
||||||
stop_registers = regcache_dup (get_current_regcache ());
|
stop_registers = regcache_dup (get_current_regcache ());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stop_stack_dummy)
|
if (stop_stack_dummy == STOP_STACK_DUMMY)
|
||||||
{
|
{
|
||||||
/* Pop the empty frame that contains the stack dummy.
|
/* Pop the empty frame that contains the stack dummy.
|
||||||
This also restores inferior state prior to the call
|
This also restores inferior state prior to the call
|
||||||
|
@ -6038,7 +6038,7 @@ struct inferior_status
|
||||||
{
|
{
|
||||||
bpstat stop_bpstat;
|
bpstat stop_bpstat;
|
||||||
int stop_step;
|
int stop_step;
|
||||||
int stop_stack_dummy;
|
enum stop_stack_kind stop_stack_dummy;
|
||||||
int stopped_by_random_signal;
|
int stopped_by_random_signal;
|
||||||
int stepping_over_breakpoint;
|
int stepping_over_breakpoint;
|
||||||
CORE_ADDR step_range_start;
|
CORE_ADDR step_range_start;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue