2011-09-09 Pedro Alves gdb/ * breakpoint.c (bpstat_check_location, bpstat_stop_status) : 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) : Add `ws' parameter. (bpstat_stop_status): Same. * infrun.c (handle_syscall_event, handle_inferior_event): Adjust to pass the current event's waitstatus to bpstat_stop_status. --- gdb/breakpoint.c | 45 ++++++++++++++++++++++++++++++++------------- gdb/breakpoint.h | 5 +++-- gdb/infrun.c | 11 ++++++----- 3 files changed, 41 insertions(+), 20 deletions(-) Index: src/gdb/breakpoint.c =================================================================== --- src.orig/gdb/breakpoint.c 2011-09-09 16:17:32.000000000 +0100 +++ src/gdb/breakpoint.c 2011-09-09 16:33:26.509763222 +0100 @@ -3749,14 +3749,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, + 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 @@ -4066,7 +4067,8 @@ bpstat_check_breakpoint_conditions (bpst bpstat bpstat_stop_status (struct address_space *aspace, - CORE_ADDR bp_addr, ptid_t ptid) + CORE_ADDR bp_addr, ptid_t ptid, + struct target_waitstatus *ws) { struct breakpoint *b = NULL; struct bp_location *bl; @@ -4104,7 +4106,7 @@ bpstat_stop_status (struct address_space 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 @@ -6163,7 +6165,8 @@ remove_catch_fork (struct bp_location *b 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, + struct target_waitstatus *ws) { struct fork_catchpoint *c = (struct fork_catchpoint *) bl->owner; @@ -6259,7 +6262,8 @@ remove_catch_vfork (struct bp_location * 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, + struct target_waitstatus *ws) { struct fork_catchpoint *c = (struct fork_catchpoint *) bl->owner; @@ -6450,7 +6454,8 @@ remove_catch_syscall (struct bp_location 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, + 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 @@ -6750,7 +6755,8 @@ remove_catch_exec (struct bp_location *b 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, + struct target_waitstatus *ws) { struct exec_catchpoint *c = (struct exec_catchpoint *) bl->owner; @@ -8169,8 +8175,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, + 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); } @@ -8646,7 +8657,8 @@ remove_watchpoint (struct bp_location *b 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, + struct target_waitstatus *ws) { struct breakpoint *b = bl->owner; struct watchpoint *w = (struct watchpoint *) b; @@ -10779,7 +10791,8 @@ base_breakpoint_remove_location (struct static int base_breakpoint_breakpoint_hit (const struct bp_location *bl, struct address_space *aspace, - CORE_ADDR bp_addr) + CORE_ADDR bp_addr, + struct target_waitstatus *ws) { internal_error_pure_virtual_called (); } @@ -10893,10 +10906,15 @@ bkpt_remove_location (struct bp_location 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, + 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; @@ -11146,7 +11164,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, + struct target_waitstatus *ws) { /* By definition, the inferior does not report stops at tracepoints. */ Index: src/gdb/breakpoint.h =================================================================== --- src.orig/gdb/breakpoint.h 2011-09-09 16:17:33.139763056 +0100 +++ src/gdb/breakpoint.h 2011-09-09 16:33:26.519763222 +0100 @@ -436,7 +436,7 @@ struct breakpoint_ops 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); + CORE_ADDR, struct target_waitstatus *); /* Check internal conditions of the breakpoint referred to by BS. If we should not stop for this breakpoint, set BS->stop to 0. */ @@ -736,7 +736,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, + struct target_waitstatus *ws); /* This bpstat_what stuff tells wait_for_inferior what to do with a breakpoint (a challenging task). Index: src/gdb/infrun.c =================================================================== --- src.orig/gdb/infrun.c 2011-09-09 16:17:43.379763058 +0100 +++ src/gdb/infrun.c 2011-09-09 16:33:26.519763222 +0100 @@ -3080,7 +3080,7 @@ handle_syscall_event (struct execution_c 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); @@ -3449,7 +3449,7 @@ handle_inferior_event (struct execution_ 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. @@ -3547,7 +3547,7 @@ handle_inferior_event (struct execution_ 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); @@ -4085,10 +4085,11 @@ handle_inferior_event (struct execution_ return; } - /* See if there is a breakpoint at the current PC. */ + /* See if there is a breakpoint/watchpoint/catchpoint/etc. that + handles this signal. */ 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. */