diff --git a/lldb/source/Target/ThreadPlanStepOut.cpp b/lldb/source/Target/ThreadPlanStepOut.cpp index d49a01bdbcef7..7970e731aa972 100644 --- a/lldb/source/Target/ThreadPlanStepOut.cpp +++ b/lldb/source/Target/ThreadPlanStepOut.cpp @@ -8,6 +8,7 @@ #include "lldb/Target/ThreadPlanStepOut.h" #include "lldb/Breakpoint/Breakpoint.h" +#include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Value.h" #include "lldb/Symbol/Block.h" #include "lldb/Symbol/Function.h" @@ -306,6 +307,21 @@ bool ThreadPlanStepOut::ValidatePlan(Stream *error) { return true; } +/// Returns true if : +/// 1. All breakpoints in this site are internal, and +/// 2. All breakpoint locations in this site are NOT valid for `thread`. +static bool NoUserBreakpointsHere(BreakpointSite &site, Thread &thread) { + for (unsigned bp_idx = 0; bp_idx < site.GetNumberOfConstituents(); bp_idx++) { + BreakpointLocation &bp_loc = *site.GetConstituentAtIndex(bp_idx); + const Breakpoint &bp = bp_loc.GetBreakpoint(); + if (bp.IsInternal()) + continue; + if (bp_loc.ValidForThisThread(thread)) + return false; + } + return true; +} + bool ThreadPlanStepOut::DoPlanExplainsStop(Event *event_ptr) { // If the step out plan is done, then we just need to step through the // inlined frame. @@ -356,13 +372,10 @@ bool ThreadPlanStepOut::DoPlanExplainsStop(Event *event_ptr) { } } - // If there was only one owner, then we're done. But if we also hit - // some user breakpoint on our way out, we should mark ourselves as - // done, but also not claim to explain the stop, since it is more - // important to report the user breakpoint than the step out - // completion. - - if (site_sp->GetNumberOfConstituents() == 1) + // If the thread also hit a user breakpoint on its way out, the plan is + // done but should not claim to explain the stop. It is more important + // to report the user breakpoint than the step out completion. + if (NoUserBreakpointsHere(*site_sp, GetThread())) return true; } return false;