Changed the formerly pure virtual function:

namespace lldb_private {
    class Thread
    {
        virtual lldb::StopInfoSP
        GetPrivateStopReason() = 0;
    };
}

To not be virtual. The lldb_private::Thread now handles the correct caching and will call a new pure virtual function:

namespace lldb_private {
    class Thread
    {
        virtual bool
        CalculateStopInfo() = 0;
    }
}

This function must be overridden by thead lldb_private::Thread subclass and the only thing it needs to do is to set the Thread::StopInfo() with the current stop reason and return true, or return false if there is no stop reason. The  lldb_private::Thread class will take care of calling this function only when it is required. This allows lldb_private::Thread subclasses to be a bit simpler and not all need to duplicate the cache and invalidation settings.

Also renamed:

lldb::StopInfoSP
lldb_private::Thread::GetPrivateStopReason();

To:

lldb::StopInfoSP
lldb_private::Thread::GetPrivateStopInfo();

Also cleaned up a case where the ThreadPlanStepOverBreakpoint might not re-set its breakpoint if the thread disappears (which was happening due to a bug when using the OperatingSystem plug-ins with memory threads and real threads).



git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@181501 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Target/Thread.cpp b/source/Target/Thread.cpp
index 478021a..c4aa254 100644
--- a/source/Target/Thread.cpp
+++ b/source/Target/Thread.cpp
@@ -243,9 +243,9 @@
     UserID (tid),
     Broadcaster(&process.GetTarget().GetDebugger(), Thread::GetStaticBroadcasterClass().AsCString()),
     m_process_wp (process.shared_from_this()),
-    m_actual_stop_info_sp (),
+    m_stop_info_sp (),
+    m_stop_info_stop_id (0),
     m_index_id (process.GetNextThreadIndexID(tid)),
-    m_protocol_tid (tid),
     m_reg_context_sp (),
     m_state (eStateUnloaded),
     m_state_mutex (Mutex::eMutexTypeRecursive),
@@ -259,7 +259,6 @@
     m_temporary_resume_state (eStateRunning),
     m_unwinder_ap (),
     m_destroy_called (false),
-    m_thread_stop_reason_stop_id (0),
     m_override_should_notify (eLazyBoolCalculate)
 {
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
@@ -283,11 +282,17 @@
 void 
 Thread::DestroyThread ()
 {
+    // Tell any plans on the plan stack that the thread is being destroyed since
+    // any active plans that have a thread go away in the middle of might need
+    // to do cleanup.
+    for (auto plan : m_plan_stack)
+        plan->ThreadDestroyed();
+
     m_destroy_called = true;
     m_plan_stack.clear();
     m_discarded_plan_stack.clear();
     m_completed_plan_stack.clear();
-    m_actual_stop_info_sp.reset();
+    m_stop_info_sp.reset();
     m_reg_context_sp.reset();
     m_unwinder_ap.reset();
     Mutex::Locker locker(m_frame_mutex);
@@ -366,19 +371,58 @@
     }
     else
     {
-        if ((m_thread_stop_reason_stop_id == stop_id) ||   // Stop info is valid, just return what we have (even if empty)
-            (m_actual_stop_info_sp && m_actual_stop_info_sp->IsValid()))  // Stop info is valid, just return what we have
+        if ((m_stop_info_stop_id == stop_id) ||   // Stop info is valid, just return what we have (even if empty)
+            (m_stop_info_sp && m_stop_info_sp->IsValid()))  // Stop info is valid, just return what we have
         {
-            return m_actual_stop_info_sp;
+            return m_stop_info_sp;
         }
         else
         {
-            GetPrivateStopReason ();
-            return m_actual_stop_info_sp;
+            GetPrivateStopInfo ();
+            return m_stop_info_sp;
         }
     }
 }
 
+lldb::StopInfoSP
+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)
+            {
+                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());
+                }
+            }
+        }
+    }
+    return m_stop_info_sp;
+}
+
+
 lldb::StopReason
 Thread::GetStopReason()
 {
@@ -393,20 +437,20 @@
 void
 Thread::SetStopInfo (const lldb::StopInfoSP &stop_info_sp)
 {
-    m_actual_stop_info_sp = stop_info_sp;
-    if (m_actual_stop_info_sp)
+    m_stop_info_sp = stop_info_sp;
+    if (m_stop_info_sp)
     {
-        m_actual_stop_info_sp->MakeStopInfoValid();
+        m_stop_info_sp->MakeStopInfoValid();
         // If we are overriding the ShouldReportStop, do that here:
         if (m_override_should_notify != eLazyBoolCalculate)
-            m_actual_stop_info_sp->OverrideShouldNotify (m_override_should_notify == eLazyBoolYes);
+            m_stop_info_sp->OverrideShouldNotify (m_override_should_notify == eLazyBoolYes);
     }
     
     ProcessSP process_sp (GetProcess());
     if (process_sp)
-        m_thread_stop_reason_stop_id = process_sp->GetStopID();
+        m_stop_info_stop_id = process_sp->GetStopID();
     else
-        m_thread_stop_reason_stop_id = UINT32_MAX;
+        m_stop_info_stop_id = UINT32_MAX;
 }
 
 void
@@ -417,8 +461,8 @@
     else
     {
         m_override_should_notify = (vote == eVoteYes ? eLazyBoolYes : eLazyBoolNo);
-        if (m_actual_stop_info_sp)
-            m_actual_stop_info_sp->OverrideShouldNotify (m_override_should_notify == eLazyBoolYes);
+        if (m_stop_info_sp)
+            m_stop_info_sp->OverrideShouldNotify (m_override_should_notify == eLazyBoolYes);
     }
 }
 
@@ -433,7 +477,7 @@
 bool
 Thread::ThreadStoppedForAReason (void)
 {
-    return (bool) GetPrivateStopReason ();
+    return (bool) GetPrivateStopInfo ();
 }
 
 bool
@@ -554,18 +598,22 @@
 
     m_temporary_resume_state = resume_state;
     
-    // Make sure m_actual_stop_info_sp is valid
-    GetPrivateStopReason();
+    lldb::ThreadSP backing_thread_sp (GetBackingThread ());
+    if (backing_thread_sp)
+        backing_thread_sp->m_temporary_resume_state = resume_state;
+
+    // Make sure m_stop_info_sp is valid
+    GetPrivateStopInfo();
     
     // This is a little dubious, but we are trying to limit how often we actually fetch stop info from
     // the target, 'cause that slows down single stepping.  So assume that if we got to the point where
     // we're about to resume, and we haven't yet had to fetch the stop reason, then it doesn't need to know
     // about the fact that we are resuming...
         const uint32_t process_stop_id = GetProcess()->GetStopID();
-    if (m_thread_stop_reason_stop_id == process_stop_id &&
-        (m_actual_stop_info_sp && m_actual_stop_info_sp->IsValid()))
+    if (m_stop_info_stop_id == process_stop_id &&
+        (m_stop_info_sp && m_stop_info_sp->IsValid()))
     {
-        StopInfo *stop_info = GetPrivateStopReason().get();
+        StopInfo *stop_info = GetPrivateStopInfo().get();
         if (stop_info)
             stop_info->WillResume (resume_state);
     }
@@ -590,7 +638,7 @@
         
         if (need_to_resume && resume_state != eStateSuspended)
         {
-            m_actual_stop_info_sp.reset();
+            m_stop_info_sp.reset();
         }
     }
 
@@ -676,7 +724,7 @@
     // First query the stop info's ShouldStopSynchronous.  This handles "synchronous" stop reasons, for example the breakpoint
     // command on internal breakpoints.  If a synchronous stop reason says we should not stop, then we don't have to
     // do any more work on this stop.
-    StopInfoSP private_stop_info (GetPrivateStopReason());
+    StopInfoSP private_stop_info (GetPrivateStopInfo());
     if (private_stop_info && private_stop_info->ShouldStopSynchronous(event_ptr) == false)
     {
         if (log)
@@ -1906,10 +1954,10 @@
     // If we are currently stopped at a breakpoint, always return that stopinfo and don't reset it.
     // This allows threads to maintain their breakpoint stopinfo, such as when thread-stepping in
     // multithreaded programs.
-    if (m_actual_stop_info_sp) {
-        StopReason stop_reason = m_actual_stop_info_sp->GetStopReason();
+    if (m_stop_info_sp) {
+        StopReason stop_reason = m_stop_info_sp->GetStopReason();
         if (stop_reason == lldb::eStopReasonBreakpoint) {
-            uint64_t value = m_actual_stop_info_sp->GetValue();
+            uint64_t value = m_stop_info_sp->GetValue();
             lldb::RegisterContextSP reg_ctx_sp (GetRegisterContext());
             if (reg_ctx_sp)
             {