aboutsummaryrefslogtreecommitdiff
path: root/gdb/breakpoint.c
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2010-03-25 20:48:53 +0000
committerTom Tromey <tromey@redhat.com>2010-03-25 20:48:53 +0000
commitaa7d318d60c595f97230f45575c882c73f7bdcf7 (patch)
treec161b0a218a0050a1da51a3380ebc8d896b48dc2 /gdb/breakpoint.c
parent82ccf5a5777fc9fda05b4d107a476a69b66002dc (diff)
downloadgdb-aa7d318d60c595f97230f45575c882c73f7bdcf7.zip
gdb-aa7d318d60c595f97230f45575c882c73f7bdcf7.tar.gz
gdb-aa7d318d60c595f97230f45575c882c73f7bdcf7.tar.bz2
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.
Diffstat (limited to 'gdb/breakpoint.c')
-rw-r--r--gdb/breakpoint.c101
1 files changed, 97 insertions, 4 deletions
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 2cc1f08..ded2a55 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -2157,6 +2157,41 @@ create_longjmp_master_breakpoint (char *func_name)
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
update_breakpoints_after_exec (void)
{
@@ -2198,7 +2233,7 @@ update_breakpoints_after_exec (void)
/* Thread event breakpoints must be set anew after an exec(),
as must overlay event and longjmp master breakpoints. */
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);
continue;
@@ -2274,6 +2309,7 @@ update_breakpoints_after_exec (void)
create_longjmp_master_breakpoint ("_longjmp");
create_longjmp_master_breakpoint ("siglongjmp");
create_longjmp_master_breakpoint ("_siglongjmp");
+ create_std_terminate_master_breakpoint ("std::terminate()");
}
int
@@ -3202,6 +3238,12 @@ print_it_typical (bpstat bs)
result = PRINT_NOTHING;
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_hardware_watchpoint:
annotate_watchpoint (b->number);
@@ -3292,6 +3334,7 @@ print_it_typical (bpstat bs)
case bp_step_resume:
case bp_watchpoint_scope:
case bp_call_dummy:
+ case bp_std_terminate:
case bp_tracepoint:
case bp_fast_tracepoint:
case bp_jit_event:
@@ -4035,7 +4078,8 @@ bpstat_stop_status (struct address_space *aspace,
continue;
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. */
bs->stop = 0;
else
@@ -4245,7 +4289,7 @@ bpstat_what (bpstat bs)
enum bpstat_what_main_action current_action = BPSTAT_WHAT_KEEP_CHECKING;
struct bpstat_what retval;
- retval.call_dummy = 0;
+ retval.call_dummy = STOP_NONE;
for (; bs != NULL; bs = bs->next)
{
enum class bs_class = no_effect;
@@ -4318,6 +4362,7 @@ bpstat_what (bpstat bs)
case bp_thread_event:
case bp_overlay_event:
case bp_longjmp_master:
+ case bp_std_terminate_master:
bs_class = bp_nostop;
break;
case bp_catchpoint:
@@ -4337,7 +4382,13 @@ bpstat_what (bpstat bs)
/* Make sure the action is stop (silent or noisy),
so infrun.c pops the dummy frame. */
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;
case bp_tracepoint:
case bp_fast_tracepoint:
@@ -4465,10 +4516,12 @@ print_one_breakpoint_location (struct breakpoint *b,
{bp_step_resume, "step resume"},
{bp_watchpoint_scope, "watchpoint scope"},
{bp_call_dummy, "call dummy"},
+ {bp_std_terminate, "std::terminate"},
{bp_shlib_event, "shlib events"},
{bp_thread_event, "thread events"},
{bp_overlay_event, "overlay events"},
{bp_longjmp_master, "longjmp master"},
+ {bp_std_terminate_master, "std::terminate master"},
{bp_catchpoint, "catchpoint"},
{bp_tracepoint, "tracepoint"},
{bp_fast_tracepoint, "fast tracepoint"},
@@ -4596,10 +4649,12 @@ print_one_breakpoint_location (struct breakpoint *b,
case bp_step_resume:
case bp_watchpoint_scope:
case bp_call_dummy:
+ case bp_std_terminate:
case bp_shlib_event:
case bp_thread_event:
case bp_overlay_event:
case bp_longjmp_master:
+ case bp_std_terminate_master:
case bp_tracepoint:
case bp_fast_tracepoint:
case bp_jit_event:
@@ -5235,11 +5290,13 @@ allocate_bp_location (struct breakpoint *bpt)
case bp_step_resume:
case bp_watchpoint_scope:
case bp_call_dummy:
+ case bp_std_terminate:
case bp_shlib_event:
case bp_thread_event:
case bp_overlay_event:
case bp_jit_event:
case bp_longjmp_master:
+ case bp_std_terminate_master:
loc->loc_type = bp_loc_software_breakpoint;
break;
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 *
create_thread_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
{
@@ -6537,12 +6621,14 @@ mention (struct breakpoint *b)
case bp_longjmp_resume:
case bp_step_resume:
case bp_call_dummy:
+ case bp_std_terminate:
case bp_watchpoint_scope:
case bp_shlib_event:
case bp_thread_event:
case bp_overlay_event:
case bp_jit_event:
case bp_longjmp_master:
+ case bp_std_terminate_master:
break;
}
@@ -9222,11 +9308,13 @@ delete_command (char *arg, int from_tty)
ALL_BREAKPOINTS (b)
{
if (b->type != bp_call_dummy
+ && b->type != bp_std_terminate
&& b->type != bp_shlib_event
&& b->type != bp_jit_event
&& b->type != bp_thread_event
&& b->type != bp_overlay_event
&& b->type != bp_longjmp_master
+ && b->type != bp_std_terminate_master
&& b->number >= 0)
{
breaks_to_delete = 1;
@@ -9241,11 +9329,13 @@ delete_command (char *arg, int from_tty)
ALL_BREAKPOINTS_SAFE (b, temp)
{
if (b->type != bp_call_dummy
+ && b->type != bp_std_terminate
&& b->type != bp_shlib_event
&& b->type != bp_thread_event
&& b->type != bp_jit_event
&& b->type != bp_overlay_event
&& b->type != bp_longjmp_master
+ && b->type != bp_std_terminate_master
&& b->number >= 0)
delete_breakpoint (b);
}
@@ -9556,6 +9646,7 @@ breakpoint_re_set_one (void *bint)
reset later by breakpoint_re_set. */
case bp_overlay_event:
case bp_longjmp_master:
+ case bp_std_terminate_master:
delete_breakpoint (b);
break;
@@ -9575,6 +9666,7 @@ breakpoint_re_set_one (void *bint)
case bp_finish:
case bp_watchpoint_scope:
case bp_call_dummy:
+ case bp_std_terminate:
case bp_step_resume:
case bp_longjmp:
case bp_longjmp_resume:
@@ -9620,6 +9712,7 @@ breakpoint_re_set (void)
create_longjmp_master_breakpoint ("_longjmp");
create_longjmp_master_breakpoint ("siglongjmp");
create_longjmp_master_breakpoint ("_siglongjmp");
+ create_std_terminate_master_breakpoint ("std::terminate()");
}
/* Reset the thread number of this breakpoint: