Remove ALL_BREAKPOINTS_SAFE
There's just a single remaining use of the ALL_BREAKPOINTS_SAFE macro; this patch replaces it with a for-each and an explicit temporary variable.
This commit is contained in:
parent
8e8d48f91c
commit
7a8de0c330
128
gdb/breakpoint.c
128
gdb/breakpoint.c
@ -611,15 +611,6 @@ static int overlay_events_enabled;
|
||||
/* See description in breakpoint.h. */
|
||||
bool target_exact_watchpoints = false;
|
||||
|
||||
/* Walk the following statement or block through all breakpoints.
|
||||
ALL_BREAKPOINTS_SAFE does so even if the statement deletes the
|
||||
current breakpoint. */
|
||||
|
||||
#define ALL_BREAKPOINTS_SAFE(B,TMP) \
|
||||
for (B = breakpoint_chain; \
|
||||
B ? (TMP=B->next, 1): 0; \
|
||||
B = TMP)
|
||||
|
||||
/* Chains of all breakpoints defined. */
|
||||
|
||||
static struct breakpoint *breakpoint_chain;
|
||||
@ -7617,72 +7608,73 @@ set_longjmp_breakpoint_for_call_dummy (void)
|
||||
void
|
||||
check_longjmp_breakpoint_for_call_dummy (struct thread_info *tp)
|
||||
{
|
||||
struct breakpoint *b, *b_tmp;
|
||||
for (struct breakpoint *b : all_breakpoints_safe ())
|
||||
{
|
||||
struct breakpoint *b_tmp = b->next;
|
||||
if (b->type == bp_longjmp_call_dummy && b->thread == tp->global_num)
|
||||
{
|
||||
struct breakpoint *dummy_b = b->related_breakpoint;
|
||||
|
||||
ALL_BREAKPOINTS_SAFE (b, b_tmp)
|
||||
if (b->type == bp_longjmp_call_dummy && b->thread == tp->global_num)
|
||||
{
|
||||
struct breakpoint *dummy_b = b->related_breakpoint;
|
||||
/* Find the bp_call_dummy breakpoint in the list of breakpoints
|
||||
chained off b->related_breakpoint. */
|
||||
while (dummy_b != b && dummy_b->type != bp_call_dummy)
|
||||
dummy_b = dummy_b->related_breakpoint;
|
||||
|
||||
/* Find the bp_call_dummy breakpoint in the list of breakpoints
|
||||
chained off b->related_breakpoint. */
|
||||
while (dummy_b != b && dummy_b->type != bp_call_dummy)
|
||||
dummy_b = dummy_b->related_breakpoint;
|
||||
/* If there was no bp_call_dummy breakpoint then there's nothing
|
||||
more to do. Or, if the dummy frame associated with the
|
||||
bp_call_dummy is still on the stack then we need to leave this
|
||||
bp_call_dummy in place. */
|
||||
if (dummy_b->type != bp_call_dummy
|
||||
|| frame_find_by_id (dummy_b->frame_id) != NULL)
|
||||
continue;
|
||||
|
||||
/* If there was no bp_call_dummy breakpoint then there's nothing
|
||||
more to do. Or, if the dummy frame associated with the
|
||||
bp_call_dummy is still on the stack then we need to leave this
|
||||
bp_call_dummy in place. */
|
||||
if (dummy_b->type != bp_call_dummy
|
||||
|| frame_find_by_id (dummy_b->frame_id) != NULL)
|
||||
continue;
|
||||
/* We didn't find the dummy frame on the stack, this could be
|
||||
because we have longjmp'd to a stack frame that is previous to
|
||||
the dummy frame, or it could be because the stack unwind is
|
||||
broken at some point between the longjmp frame and the dummy
|
||||
frame.
|
||||
|
||||
/* We didn't find the dummy frame on the stack, this could be
|
||||
because we have longjmp'd to a stack frame that is previous to
|
||||
the dummy frame, or it could be because the stack unwind is
|
||||
broken at some point between the longjmp frame and the dummy
|
||||
frame.
|
||||
Next we figure out why the stack unwind stopped. If it looks
|
||||
like the unwind is complete then we assume the dummy frame has
|
||||
been jumped over, however, if the unwind stopped for an
|
||||
unexpected reason then we assume the stack unwind is currently
|
||||
broken, and that we will (eventually) return to the dummy
|
||||
frame.
|
||||
|
||||
Next we figure out why the stack unwind stopped. If it looks
|
||||
like the unwind is complete then we assume the dummy frame has
|
||||
been jumped over, however, if the unwind stopped for an
|
||||
unexpected reason then we assume the stack unwind is currently
|
||||
broken, and that we will (eventually) return to the dummy
|
||||
frame.
|
||||
It might be tempting to consider using frame_id_inner here, but
|
||||
that is not safe. There is no guarantee that the stack frames
|
||||
we are looking at here are even on the same stack as the
|
||||
original dummy frame, hence frame_id_inner can't be used. See
|
||||
the comments on frame_id_inner for more details. */
|
||||
bool unwind_finished_unexpectedly = false;
|
||||
for (frame_info_ptr fi = get_current_frame (); fi != nullptr; )
|
||||
{
|
||||
frame_info_ptr prev = get_prev_frame (fi);
|
||||
if (prev == nullptr)
|
||||
{
|
||||
/* FI is the last stack frame. Why did this frame not
|
||||
unwind further? */
|
||||
auto stop_reason = get_frame_unwind_stop_reason (fi);
|
||||
if (stop_reason != UNWIND_NO_REASON
|
||||
&& stop_reason != UNWIND_OUTERMOST)
|
||||
unwind_finished_unexpectedly = true;
|
||||
}
|
||||
fi = prev;
|
||||
}
|
||||
if (unwind_finished_unexpectedly)
|
||||
continue;
|
||||
|
||||
It might be tempting to consider using frame_id_inner here, but
|
||||
that is not safe. There is no guarantee that the stack frames
|
||||
we are looking at here are even on the same stack as the
|
||||
original dummy frame, hence frame_id_inner can't be used. See
|
||||
the comments on frame_id_inner for more details. */
|
||||
bool unwind_finished_unexpectedly = false;
|
||||
for (frame_info_ptr fi = get_current_frame (); fi != nullptr; )
|
||||
{
|
||||
frame_info_ptr prev = get_prev_frame (fi);
|
||||
if (prev == nullptr)
|
||||
{
|
||||
/* FI is the last stack frame. Why did this frame not
|
||||
unwind further? */
|
||||
auto stop_reason = get_frame_unwind_stop_reason (fi);
|
||||
if (stop_reason != UNWIND_NO_REASON
|
||||
&& stop_reason != UNWIND_OUTERMOST)
|
||||
unwind_finished_unexpectedly = true;
|
||||
}
|
||||
fi = prev;
|
||||
}
|
||||
if (unwind_finished_unexpectedly)
|
||||
continue;
|
||||
dummy_frame_discard (dummy_b->frame_id, tp);
|
||||
|
||||
dummy_frame_discard (dummy_b->frame_id, tp);
|
||||
|
||||
while (b->related_breakpoint != b)
|
||||
{
|
||||
if (b_tmp == b->related_breakpoint)
|
||||
b_tmp = b->related_breakpoint->next;
|
||||
delete_breakpoint (b->related_breakpoint);
|
||||
}
|
||||
delete_breakpoint (b);
|
||||
}
|
||||
while (b->related_breakpoint != b)
|
||||
{
|
||||
if (b_tmp == b->related_breakpoint)
|
||||
b_tmp = b->related_breakpoint->next;
|
||||
delete_breakpoint (b->related_breakpoint);
|
||||
}
|
||||
delete_breakpoint (b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
x
Reference in New Issue
Block a user