diff --git a/lldb/include/lldb/Target/Thread.h b/lldb/include/lldb/Target/Thread.h index fc58a6903b6f..d0984c6d45a3 100644 --- a/lldb/include/lldb/Target/Thread.h +++ b/lldb/include/lldb/Target/Thread.h @@ -895,9 +895,19 @@ public: return !m_destroy_called; } - // When you implement this method, make sure you don't overwrite the m_actual_stop_info if it claims to be - // valid. The stop info may be a "checkpointed and restored" stop info, so if it is still around it is right - // even if you have not calculated this yourself, or if it disagrees with what you might have calculated. + // Sets and returns a valid stop info based on the process stop ID and the + // current thread plan. If the thread stop ID does not match the process' + // stop ID, the private stop reason is not set and an invalid StopInfoSP may + // be returned. + // + // NOTE: This function must be called before the current thread plan is + // moved to the completed plan stack (in Thread::ShouldStop()). + // + // NOTE: If subclasses override this function, ensure they do not overwrite + // the m_actual_stop_info if it is valid. The stop info may be a + // "checkpointed and restored" stop info, so if it is still around it is + // right even if you have not calculated this yourself, or if it disagrees + // with what you might have calculated. virtual lldb::StopInfoSP GetPrivateStopInfo (); diff --git a/lldb/include/lldb/Target/ThreadPlan.h b/lldb/include/lldb/Target/ThreadPlan.h index 5e02ec74489d..9c4259dff51c 100644 --- a/lldb/include/lldb/Target/ThreadPlan.h +++ b/lldb/include/lldb/Target/ThreadPlan.h @@ -516,6 +516,12 @@ public: // Nothing to do in general. return true; } + + virtual bool + IsVirtualStep() + { + return false; + } protected: //------------------------------------------------------------------ diff --git a/lldb/include/lldb/Target/ThreadPlanStepInRange.h b/lldb/include/lldb/Target/ThreadPlanStepInRange.h index f9e64ce2cedd..158c8605df32 100644 --- a/lldb/include/lldb/Target/ThreadPlanStepInRange.h +++ b/lldb/include/lldb/Target/ThreadPlanStepInRange.h @@ -60,6 +60,9 @@ public: static void SetDefaultFlagValue (uint32_t new_value); + bool + IsVirtualStep(); + protected: virtual bool DoWillResume (lldb::StateType resume_state, bool current_plan); diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index c4aa25446823..9abf514ab46b 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -390,32 +390,23 @@ Thread::GetPrivateStopInfo () ProcessSP process_sp (GetProcess()); if (process_sp) { - ProcessSP process_sp (GetProcess()); - if (process_sp) + const uint32_t process_stop_id = process_sp->GetStopID(); + if (m_stop_info_stop_id != process_stop_id) { - const uint32_t process_stop_id = process_sp->GetStopID(); - if (m_stop_info_stop_id != process_stop_id) + if (m_stop_info_sp) { - if (m_stop_info_sp) - { - if (m_stop_info_sp->IsValid()) - { - SetStopInfo (m_stop_info_sp); - } - else - { - if (IsStillAtLastBreakpointHit()) - SetStopInfo(m_stop_info_sp); - else - m_stop_info_sp.reset(); - } - } - - if (!m_stop_info_sp) - { - if (CalculateStopInfo() == false) - SetStopInfo (StopInfoSP()); - } + if (m_stop_info_sp->IsValid() + || IsStillAtLastBreakpointHit() + || GetCurrentPlan()->IsVirtualStep()) + SetStopInfo (m_stop_info_sp); + else + m_stop_info_sp.reset(); + } + + if (!m_stop_info_sp) + { + if (CalculateStopInfo() == false) + SetStopInfo (StopInfoSP()); } } } @@ -693,6 +684,10 @@ Thread::ShouldStop (Event* event_ptr) return false; } + // Based on the current thread plan and process stop info, check if this + // thread caused the process to stop. NOTE: this must take place before + // the plan is moved from the current plan stack to the completed plan + // stack. if (ThreadStoppedForAReason() == false) { if (log) diff --git a/lldb/source/Target/ThreadPlanStepInRange.cpp b/lldb/source/Target/ThreadPlanStepInRange.cpp index d5a6b10858f2..c5bb14464790 100644 --- a/lldb/source/Target/ThreadPlanStepInRange.cpp +++ b/lldb/source/Target/ThreadPlanStepInRange.cpp @@ -463,3 +463,9 @@ ThreadPlanStepInRange::DoWillResume (lldb::StateType resume_state, bool current_ } return true; } + +bool +ThreadPlanStepInRange::IsVirtualStep() +{ + return m_virtual_step; +}