mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-03-03 23:17:25 +00:00
* infrun.c (handle_inferior_event): Hardware hatchpoint traps are
never random signals. * breakpoint.c (update_global_location_list): Always delete immediately delete hardware watchpoint locations and other locations whose target address isn't meaningful. Update comment explaining the hazard of moribund locations.
This commit is contained in:
parent
eb6cdd53bf
commit
db82e815be
@ -1,3 +1,12 @@
|
||||
2009-11-20 Pedro Alves <pedro@codesourcery.com>
|
||||
|
||||
* infrun.c (handle_inferior_event): Hardware hatchpoint traps are
|
||||
never random signals.
|
||||
* breakpoint.c (update_global_location_list): Always delete
|
||||
immediately delete hardware watchpoint locations and other
|
||||
locations whose target address isn't meaningful. Update comment
|
||||
explaining the hazard of moribund locations.
|
||||
|
||||
2009-11-19 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* ada-lang.c (discrete_type_p): TYPE_CODE_BOOL is also a discrete type.
|
||||
|
@ -8300,20 +8300,55 @@ update_global_location_list (int should_insert)
|
||||
|
||||
if (!found_object)
|
||||
{
|
||||
if (removed && non_stop)
|
||||
if (removed && non_stop
|
||||
&& breakpoint_address_is_meaningful (old_loc->owner)
|
||||
&& !is_hardware_watchpoint (old_loc->owner))
|
||||
{
|
||||
/* This location was removed from the targets. In non-stop mode,
|
||||
a race condition is possible where we've removed a breakpoint,
|
||||
but stop events for that breakpoint are already queued and will
|
||||
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,
|
||||
"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
|
||||
heuristic, but if it's wrong, we'll report unexpected SIGTRAP,
|
||||
which is usability issue, but not a correctness problem. */
|
||||
/* This location was removed from the target. In
|
||||
non-stop mode, a race condition is possible where
|
||||
we've removed a breakpoint, but stop events for that
|
||||
breakpoint are already queued and will arrive later.
|
||||
We apply an heuristic to be able to distinguish such
|
||||
SIGTRAPs from other random SIGTRAPs: we keep this
|
||||
breakpoint location for a bit, and will retire it
|
||||
after we see some number of events. The theory here
|
||||
is that reporting of events should, "on the average",
|
||||
be fair, so after a while we'll see events from all
|
||||
threads that have anything of interest, and no longer
|
||||
need to keep this breakpoint location around. We
|
||||
don't hold locations forever so to reduce chances of
|
||||
mistaking a non-breakpoint SIGTRAP for a breakpoint
|
||||
SIGTRAP.
|
||||
|
||||
The heuristic failing can be disastrous on
|
||||
decr_pc_after_break targets.
|
||||
|
||||
On decr_pc_after_break targets, like e.g., x86-linux,
|
||||
if we fail to recognize a late breakpoint SIGTRAP,
|
||||
because events_till_retirement has reached 0 too
|
||||
soon, we'll fail to do the PC adjustment, and report
|
||||
a random SIGTRAP to the user. When the user resumes
|
||||
the inferior, it will most likely immediately crash
|
||||
with SIGILL/SIGBUS/SEGSEGV, or worse, get silently
|
||||
corrupted, because of being resumed e.g., in the
|
||||
middle of a multi-byte instruction, or skipped a
|
||||
one-byte instruction. This was actually seen happen
|
||||
on native x86-linux, and should be less rare on
|
||||
targets that do not support new thread events, like
|
||||
remote, due to the heuristic depending on
|
||||
thread_count.
|
||||
|
||||
Mistaking a random SIGTRAP for a breakpoint trap
|
||||
causes similar symptoms (PC adjustment applied when
|
||||
it shouldn't), but then again, playing with SIGTRAPs
|
||||
behind the debugger's back is asking for trouble.
|
||||
|
||||
Since hardware watchpoint traps are always
|
||||
distinguishable from other traps, so we don't need to
|
||||
apply keep hardware watchpoint moribund locations
|
||||
around. We simply always ignore hardware watchpoint
|
||||
traps we can no longer explain. */
|
||||
|
||||
old_loc->events_till_retirement = 3 * (thread_count () + 1);
|
||||
old_loc->owner = NULL;
|
||||
|
||||
|
16
gdb/infrun.c
16
gdb/infrun.c
@ -3593,6 +3593,21 @@ targets should add new threads to the thread list themselves in non-stop mode.")
|
||||
function. */
|
||||
stop_print_frame = 1;
|
||||
|
||||
/* This is where we handle "moribund" watchpoints. Unlike
|
||||
software breakpoints traps, hardware watchpoint traps are
|
||||
always distinguishable from random traps. If no high-level
|
||||
watchpoint is associated with the reported stop data address
|
||||
anymore, then the bpstat does not explain the signal ---
|
||||
simply make sure to ignore it if `stopped_by_watchpoint' is
|
||||
set. */
|
||||
|
||||
if (debug_infrun
|
||||
&& ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP
|
||||
&& !bpstat_explains_signal (ecs->event_thread->stop_bpstat)
|
||||
&& stopped_by_watchpoint)
|
||||
fprintf_unfiltered (gdb_stdlog, "\
|
||||
infrun: no user watchpoint explains watchpoint SIGTRAP, ignoring\n");
|
||||
|
||||
/* NOTE: cagney/2003-03-29: These two checks for a random signal
|
||||
at one stage in the past included checks for an inferior
|
||||
function call's call dummy's return breakpoint. The original
|
||||
@ -3616,6 +3631,7 @@ targets should add new threads to the thread list themselves in non-stop mode.")
|
||||
if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP)
|
||||
ecs->random_signal
|
||||
= !(bpstat_explains_signal (ecs->event_thread->stop_bpstat)
|
||||
|| stopped_by_watchpoint
|
||||
|| ecs->event_thread->trap_expected
|
||||
|| (ecs->event_thread->step_range_end
|
||||
&& ecs->event_thread->step_resume_breakpoint == NULL));
|
||||
|
Loading…
x
Reference in New Issue
Block a user