diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 22 | ||||
-rw-r--r-- | gdb/breakpoint.c | 50 | ||||
-rw-r--r-- | gdb/breakpoint.h | 17 | ||||
-rw-r--r-- | gdb/infrun.c | 16 |
4 files changed, 78 insertions, 27 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e043046..2a84aa4 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,25 @@ +2012-01-24 Pedro Alves <palves@redhat.com> + + * breakpoint.c (bpstat_check_location, bpstat_stop_status, + pc_at_non_inline_function): Add `ws' parameter, and pass it down. + (breakpoint_hit_catch_fork, breakpoint_hit_catch_vfork) + (breakpoint_hit_catch_syscall, breakpoint_hit_catch_exec): Add + `ws' parameter. + (breakpoint_hit_ranged_breakpoint): Add `ws' parameter. Return + false for events other than TARGET_SIGNAL_TRAP. + (breakpoint_hit_watchpoint, base_breakpoint_breakpoint_hit): + Add `ws' parameter. + (bkpt_breakpoint_hit): Add `ws' parameter. Return false for + events other than TARGET_SIGNAL_TRAP. + (tracepoint_breakpoint_hit): Add `ws' parameter. + * breakpoint.h (struct breakpoint_ops) <breakpoint_hit>: Add `ws' + parameter. + (bpstat_stop_status): Same. + (pc_at_non_inline_function): Same. + * infrun.c (handle_syscall_event, handle_inferior_event): Adjust + to pass the current event's waitstatus to bpstat_stop_status + and pc_at_non_inline_function. + 2012-01-24 Jan Kratochvil <jan.kratochvil@redhat.com> Code cleanup. diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 2d1dad1..6181c49 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -3825,14 +3825,15 @@ which its expression is valid.\n"); static int bpstat_check_location (const struct bp_location *bl, - struct address_space *aspace, CORE_ADDR bp_addr) + struct address_space *aspace, CORE_ADDR bp_addr, + const struct target_waitstatus *ws) { struct breakpoint *b = bl->owner; /* BL is from an existing breakpoint. */ gdb_assert (b != NULL); - return b->ops->breakpoint_hit (bl, aspace, bp_addr); + return b->ops->breakpoint_hit (bl, aspace, bp_addr, ws); } /* Determine if the watched values have actually changed, and we @@ -4142,7 +4143,8 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid) bpstat bpstat_stop_status (struct address_space *aspace, - CORE_ADDR bp_addr, ptid_t ptid) + CORE_ADDR bp_addr, ptid_t ptid, + const struct target_waitstatus *ws) { struct breakpoint *b = NULL; struct bp_location *bl; @@ -4180,7 +4182,7 @@ bpstat_stop_status (struct address_space *aspace, if (bl->shlib_disabled) continue; - if (!bpstat_check_location (bl, aspace, bp_addr)) + if (!bpstat_check_location (bl, aspace, bp_addr, ws)) continue; /* Come here if it's a watchpoint, or if the break address @@ -6225,7 +6227,8 @@ remove_catch_fork (struct bp_location *bl) static int breakpoint_hit_catch_fork (const struct bp_location *bl, - struct address_space *aspace, CORE_ADDR bp_addr) + struct address_space *aspace, CORE_ADDR bp_addr, + const struct target_waitstatus *ws) { struct fork_catchpoint *c = (struct fork_catchpoint *) bl->owner; @@ -6334,7 +6337,8 @@ remove_catch_vfork (struct bp_location *bl) static int breakpoint_hit_catch_vfork (const struct bp_location *bl, - struct address_space *aspace, CORE_ADDR bp_addr) + struct address_space *aspace, CORE_ADDR bp_addr, + const struct target_waitstatus *ws) { struct fork_catchpoint *c = (struct fork_catchpoint *) bl->owner; @@ -6538,7 +6542,8 @@ remove_catch_syscall (struct bp_location *bl) static int breakpoint_hit_catch_syscall (const struct bp_location *bl, - struct address_space *aspace, CORE_ADDR bp_addr) + struct address_space *aspace, CORE_ADDR bp_addr, + const struct target_waitstatus *ws) { /* We must check if we are catching specific syscalls in this breakpoint. If we are, then we must guarantee that the called @@ -6850,7 +6855,8 @@ remove_catch_exec (struct bp_location *bl) static int breakpoint_hit_catch_exec (const struct bp_location *bl, - struct address_space *aspace, CORE_ADDR bp_addr) + struct address_space *aspace, CORE_ADDR bp_addr, + const struct target_waitstatus *ws) { struct exec_catchpoint *c = (struct exec_catchpoint *) bl->owner; @@ -8094,8 +8100,13 @@ stopat_command (char *arg, int from_tty) static int breakpoint_hit_ranged_breakpoint (const struct bp_location *bl, struct address_space *aspace, - CORE_ADDR bp_addr) + CORE_ADDR bp_addr, + const struct target_waitstatus *ws) { + if (ws->kind != TARGET_WAITKIND_STOPPED + || ws->value.sig != TARGET_SIGNAL_TRAP) + return 0; + return breakpoint_address_match_range (bl->pspace->aspace, bl->address, bl->length, aspace, bp_addr); } @@ -8562,7 +8573,8 @@ remove_watchpoint (struct bp_location *bl) static int breakpoint_hit_watchpoint (const struct bp_location *bl, - struct address_space *aspace, CORE_ADDR bp_addr) + struct address_space *aspace, CORE_ADDR bp_addr, + const struct target_waitstatus *ws) { struct breakpoint *b = bl->owner; struct watchpoint *w = (struct watchpoint *) b; @@ -10821,7 +10833,8 @@ base_breakpoint_remove_location (struct bp_location *bl) static int base_breakpoint_breakpoint_hit (const struct bp_location *bl, struct address_space *aspace, - CORE_ADDR bp_addr) + CORE_ADDR bp_addr, + const struct target_waitstatus *ws) { internal_error_pure_virtual_called (); } @@ -10967,10 +10980,15 @@ bkpt_remove_location (struct bp_location *bl) static int bkpt_breakpoint_hit (const struct bp_location *bl, - struct address_space *aspace, CORE_ADDR bp_addr) + struct address_space *aspace, CORE_ADDR bp_addr, + const struct target_waitstatus *ws) { struct breakpoint *b = bl->owner; + if (ws->kind != TARGET_WAITKIND_STOPPED + || ws->value.sig != TARGET_SIGNAL_TRAP) + return 0; + if (!breakpoint_address_match (bl->pspace->aspace, bl->address, aspace, bp_addr)) return 0; @@ -11271,7 +11289,8 @@ tracepoint_re_set (struct breakpoint *b) static int tracepoint_breakpoint_hit (const struct bp_location *bl, - struct address_space *aspace, CORE_ADDR bp_addr) + struct address_space *aspace, CORE_ADDR bp_addr, + const struct target_waitstatus *ws) { /* By definition, the inferior does not report stops at tracepoints. */ @@ -13626,7 +13645,8 @@ is_non_inline_function (struct breakpoint *b) have been inlined. */ int -pc_at_non_inline_function (struct address_space *aspace, CORE_ADDR pc) +pc_at_non_inline_function (struct address_space *aspace, CORE_ADDR pc, + const struct target_waitstatus *ws) { struct breakpoint *b; struct bp_location *bl; @@ -13639,7 +13659,7 @@ pc_at_non_inline_function (struct address_space *aspace, CORE_ADDR pc) for (bl = b->loc; bl != NULL; bl = bl->next) { if (!bl->shlib_disabled - && bpstat_check_location (bl, aspace, pc)) + && bpstat_check_location (bl, aspace, pc, ws)) return 1; } } diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h index 8a8d5f2..dbae228 100644 --- a/gdb/breakpoint.h +++ b/gdb/breakpoint.h @@ -438,9 +438,14 @@ struct breakpoint_ops /* Return true if it the target has stopped due to hitting breakpoint location BL. This function does not check if we - should stop, only if BL explains the stop. */ - int (*breakpoint_hit) (const struct bp_location *bl, struct address_space *, - CORE_ADDR); + should stop, only if BL explains the stop. ASPACE is the address + space in which the event occurred, BP_ADDR is the address at + which the inferior stopped, and WS is the target_waitstatus + describing the event. */ + int (*breakpoint_hit) (const struct bp_location *bl, + struct address_space *aspace, + CORE_ADDR bp_addr, + const struct target_waitstatus *ws); /* Check internal conditions of the breakpoint referred to by BS. If we should not stop for this breakpoint, set BS->stop to 0. */ @@ -774,7 +779,8 @@ extern void bpstat_clear (bpstat *); extern bpstat bpstat_copy (bpstat); extern bpstat bpstat_stop_status (struct address_space *aspace, - CORE_ADDR pc, ptid_t ptid); + CORE_ADDR pc, ptid_t ptid, + const struct target_waitstatus *ws); /* This bpstat_what stuff tells wait_for_inferior what to do with a breakpoint (a challenging task). @@ -1405,7 +1411,8 @@ extern struct breakpoint *iterate_over_breakpoints (int (*) (struct breakpoint * have been inlined. */ extern int pc_at_non_inline_function (struct address_space *aspace, - CORE_ADDR pc); + CORE_ADDR pc, + const struct target_waitstatus *ws); extern int user_breakpoint_p (struct breakpoint *); diff --git a/gdb/infrun.c b/gdb/infrun.c index 24d2720..23a4bba 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -3086,7 +3086,7 @@ handle_syscall_event (struct execution_control_state *ecs) ecs->event_thread->control.stop_bpstat = bpstat_stop_status (get_regcache_aspace (regcache), - stop_pc, ecs->ptid); + stop_pc, ecs->ptid, &ecs->ws); ecs->random_signal = !bpstat_explains_signal (ecs->event_thread->control.stop_bpstat); @@ -3537,7 +3537,7 @@ handle_inferior_event (struct execution_control_state *ecs) ecs->event_thread->control.stop_bpstat = bpstat_stop_status (get_regcache_aspace (get_current_regcache ()), - stop_pc, ecs->ptid); + stop_pc, ecs->ptid, &ecs->ws); /* Note that we're interested in knowing the bpstat actually causes a stop, not just if it may explain the signal. @@ -3635,7 +3635,7 @@ handle_inferior_event (struct execution_control_state *ecs) ecs->event_thread->control.stop_bpstat = bpstat_stop_status (get_regcache_aspace (get_current_regcache ()), - stop_pc, ecs->ptid); + stop_pc, ecs->ptid, &ecs->ws); ecs->random_signal = !bpstat_explains_signal (ecs->event_thread->control.stop_bpstat); @@ -4094,11 +4094,12 @@ handle_inferior_event (struct execution_control_state *ecs) user had set a breakpoint on that inlined code, the missing skip_inline_frames call would break things. Fortunately that's an extremely unlikely scenario. */ - if (!pc_at_non_inline_function (aspace, stop_pc) + if (!pc_at_non_inline_function (aspace, stop_pc, &ecs->ws) && !(ecs->event_thread->suspend.stop_signal == TARGET_SIGNAL_TRAP && ecs->event_thread->control.trap_expected && pc_at_non_inline_function (aspace, - ecs->event_thread->prev_pc))) + ecs->event_thread->prev_pc, + &ecs->ws))) skip_inline_frames (ecs->ptid); } @@ -4200,10 +4201,11 @@ handle_inferior_event (struct execution_control_state *ecs) return; } - /* See if there is a breakpoint at the current PC. */ + /* See if there is a breakpoint/watchpoint/catchpoint/etc. that + handles this event. */ ecs->event_thread->control.stop_bpstat = bpstat_stop_status (get_regcache_aspace (get_current_regcache ()), - stop_pc, ecs->ptid); + stop_pc, ecs->ptid, &ecs->ws); /* Following in case break condition called a function. */ |