Skip to content

Commit

Permalink
Remove ALL_BREAKPOINTS_SAFE
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tromey committed May 7, 2023
1 parent 8e8d48f commit 7a8de0c
Showing 1 changed file with 63 additions and 71 deletions.
134 changes: 63 additions & 71 deletions gdb/breakpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

/* 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;
/* 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;

/* 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.
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;
/* 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;

dummy_frame_discard (dummy_b->frame_id, tp);
/* 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.
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;

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);
}
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);
}
}
}

void
Expand Down

0 comments on commit 7a8de0c

Please sign in to comment.