diff options
author | Pedro Alves <palves@redhat.com> | 2008-10-15 19:15:34 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2008-10-15 19:15:34 +0000 |
commit | 1c5cfe8615a947f26ef1569f3af3017bb1c63899 (patch) | |
tree | 67c00221d017a285eaf67bc17815044541a57d9f /gdb/breakpoint.c | |
parent | 41702f1b3391a34327b3fb4786b690583c1249b6 (diff) | |
download | gdb-1c5cfe8615a947f26ef1569f3af3017bb1c63899.zip gdb-1c5cfe8615a947f26ef1569f3af3017bb1c63899.tar.gz gdb-1c5cfe8615a947f26ef1569f3af3017bb1c63899.tar.bz2 |
gdb/
* breakpoint.c (breakpoint_init_inferior): Clean up the moribund
locations list.
(moribund_breakpoint_here_p): Record the moribund
location in the moribund_locations vector.
* breakpoint.h (moribund_breakpoint_here_p): Declare.
(displaced_step_fixup): Check if the breakpoint the thread was
trying to step over has been removed since having been placed in
the displaced stepping queue.
(adjust_pc_after_break): In non-stop mode, check for a moribund
breakpoint at the stop pc.
(handle_inferior_event): Don't retire moribund breakpoints on
TARGET_WAITKIND_IGNORE.
gdb/testsuite/
* gdb.mi/mi-nsmoribund.exp, gdb.mi/nsmoribund.c: New test.
Diffstat (limited to 'gdb/breakpoint.c')
-rw-r--r-- | gdb/breakpoint.c | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index b289ead..7f535df 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -1744,6 +1744,7 @@ breakpoint_init_inferior (enum inf_context context) { struct breakpoint *b, *temp; struct bp_location *bpt; + int ix; ALL_BP_LOCATIONS (bpt) if (bpt->owner->enable_state != bp_permanent) @@ -1786,6 +1787,11 @@ breakpoint_init_inferior (enum inf_context context) break; } } + + /* Get rid of the moribund locations. */ + for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, bpt); ++ix) + free_bp_location (bpt); + VEC_free (bp_location_p, moribund_locations); } /* breakpoint_here_p (PC) returns non-zero if an enabled breakpoint @@ -1828,6 +1834,20 @@ breakpoint_here_p (CORE_ADDR pc) return any_breakpoint_here ? ordinary_breakpoint_here : 0; } +/* Return true if there's a moribund breakpoint at PC. */ + +int +moribund_breakpoint_here_p (CORE_ADDR pc) +{ + struct bp_location *loc; + int ix; + + for (ix = 0; VEC_iterate (bp_location_p, moribund_locations, ix, loc); ++ix) + if (loc->address == pc) + return 1; + + return 0; +} /* Returns non-zero if there's a breakpoint inserted at PC, which is inserted using regular breakpoint_chain/bp_location_chain mechanism. @@ -7107,8 +7127,8 @@ update_global_location_list (int should_insert) } if (!found_object) - { - if (removed) + { + if (removed && non_stop) { /* This location was removed from the targets. In non-stop mode, a race condition is possible where we've removed a breakpoint, @@ -7116,20 +7136,22 @@ update_global_location_list (int should_insert) arrive later. To suppress spurious SIGTRAPs reported to user, we keep this breakpoint location for a bit, and will retire it after we see 3 * thread_count events. - The theory here is that reporting of events should, + The theory here is that reporting of events should, "on the average", be fair, so after that many event we'll see events from all threads that have anything of interest, and no - longer need to keep this breakpoint. This is just a + longer need to keep this breakpoint. This is just a heuristic, but if it's wrong, we'll report unexpected SIGTRAP, - which is usability issue, but not a correctness problem. */ + which is usability issue, but not a correctness problem. */ loc->events_till_retirement = 3 * (thread_count () + 1); loc->owner = NULL; - } - free_bp_location (loc); + VEC_safe_push (bp_location_p, moribund_locations, loc); + } + else + free_bp_location (loc); } } - + ALL_BREAKPOINTS (b) { check_duplicates (b); |