[Lldb-commits] [lldb] r135655 - in /lldb/trunk/tools/debugserver/source/MacOSX: MachThread.cpp MachThread.h MachThreadList.cpp

Jim Ingham jingham at apple.com
Wed Jul 20 18:54:41 PDT 2011


Author: jingham
Date: Wed Jul 20 20:54:41 2011
New Revision: 135655

URL: http://llvm.org/viewvc/llvm-project?rev=135655&view=rev
Log:
If we are telling only one thread to run in debugserver, and that thread has been suspended from outside
the debugger, resume it before running so we will actually make progress.

Modified:
    lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h
    lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp?rev=135655&r1=135654&r2=135655&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp Wed Jul 20 20:54:41 2011
@@ -48,7 +48,7 @@
 
 
 
-uint32_t
+void
 MachThread::Suspend()
 {
     DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )", __FUNCTION__);
@@ -60,27 +60,69 @@
         if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail())
             err.LogThreaded("::thread_suspend (%4.4x)", m_tid);
     }
-    return SuspendCount();
 }
 
-uint32_t
-MachThread::Resume()
+void
+MachThread::Resume(bool others_stopped)
 {
     DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )", __FUNCTION__);
     if (ThreadIDIsValid(m_tid))
     {
-        RestoreSuspendCount();
+        SetSuspendCountBeforeResume(others_stopped);
     }
-    return SuspendCount();
 }
 
 bool
-MachThread::RestoreSuspendCount()
+MachThread::SetSuspendCountBeforeResume(bool others_stopped)
 {
     DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )", __FUNCTION__);
     DNBError err;
     if (ThreadIDIsValid(m_tid) == false)
         return false;
+        
+    size_t times_to_resume;
+        
+    if (others_stopped)
+    {
+        times_to_resume = GetBasicInfo()->suspend_count;
+        m_suspendCount = - (times_to_resume - m_suspendCount);
+    }
+    else
+    {
+        times_to_resume = m_suspendCount;
+        m_suspendCount = 0;
+    }
+
+    if (times_to_resume > 0)
+    {
+        while (times_to_resume > 0)
+        {
+            err = ::thread_resume (m_tid);
+            if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail())
+                err.LogThreaded("::thread_resume (%4.4x)", m_tid);
+            if (err.Success())
+                --times_to_resume;
+            else
+            {
+                if (GetBasicInfo())
+                    times_to_resume = m_basicInfo.suspend_count;
+                else
+                    times_to_resume = 0;
+                return false; // ??? 
+            }
+        }
+    }
+    return true;
+}
+
+bool
+MachThread::RestoreSuspendCountAfterStop ()
+{
+    DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )", __FUNCTION__);
+    DNBError err;
+    if (ThreadIDIsValid(m_tid) == false)
+        return false;
+        
     if (m_suspendCount > 0)
     {
         while (m_suspendCount > 0)
@@ -100,20 +142,17 @@
             }
         }
     }
-    // We don't currently really support resuming a thread that was externally
-    // suspended. If/when we do, we will need to make the code below work and
-    // m_suspendCount will need to become signed instead of unsigned.
-//    else if (m_suspendCount < 0)
-//    {
-//        while (m_suspendCount < 0)
-//        {
-//            err = ::thread_suspend (m_tid);
-//            if (err.Success())
-//                ++m_suspendCount;
-//            if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail())
-//                err.LogThreaded("::thread_suspend (%4.4x)", m_tid);
-//        }
-//    }
+    else if (m_suspendCount < 0)
+    {
+        while (m_suspendCount < 0)
+        {
+            err = ::thread_suspend (m_tid);
+            if (err.Success())
+                ++m_suspendCount;
+            if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail())
+                err.LogThreaded("::thread_suspend (%4.4x)", m_tid);
+        }
+    }
     return true;
 }
 
@@ -317,7 +356,7 @@
 }
 
 void
-MachThread::ThreadWillResume(const DNBThreadResumeAction *thread_action)
+MachThread::ThreadWillResume(const DNBThreadResumeAction *thread_action, bool others_stopped)
 {
     if (thread_action->addr != INVALID_NUB_ADDRESS)
         SetPC (thread_action->addr);
@@ -327,12 +366,13 @@
     {
     case eStateStopped:
     case eStateSuspended:
+        assert (others_stopped == false);
         Suspend();
         break;
 
     case eStateRunning:
     case eStateStepping:
-        Resume();
+        Resume(others_stopped);
         break;
     default: 
         break;
@@ -437,7 +477,7 @@
     // We may have suspended this thread so the primary thread could step
     // without worrying about race conditions, so lets restore our suspend
     // count.
-    RestoreSuspendCount();
+    RestoreSuspendCountAfterStop();
 
     // Update the basic information for a thread
     MachThread::GetBasicInfo(m_tid, &m_basicInfo);

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h?rev=135655&r1=135654&r2=135655&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h Wed Jul 20 20:54:41 2011
@@ -49,10 +49,10 @@
 
     uint32_t        SequenceID() const { return m_seq_id; }
     static bool     ThreadIDIsValid(thread_t thread);
-    uint32_t        Resume();
-    uint32_t        Suspend();
-    uint32_t        SuspendCount() const { return m_suspendCount; }
-    bool            RestoreSuspendCount();
+    void            Resume(bool others_stopped);
+    void            Suspend();
+    bool            SetSuspendCountBeforeResume(bool others_stopped);
+    bool            RestoreSuspendCountAfterStop();
 
     bool            GetRegisterState(int flavor, bool force);
     bool            SetRegisterState(int flavor);
@@ -69,7 +69,7 @@
     nub_state_t     GetState();
     void            SetState(nub_state_t state);
 
-    void            ThreadWillResume (const DNBThreadResumeAction *thread_action);
+    void            ThreadWillResume (const DNBThreadResumeAction *thread_action, bool others_stopped = false);
     bool            ShouldStop(bool &step_more);
     bool            IsStepping();
     bool            ThreadDidStop();
@@ -119,7 +119,8 @@
     PThreadMutex                    m_state_mutex;  // Multithreaded protection for m_state
     nub_break_t                     m_breakID;      // Breakpoint that this thread is (stopped)/was(running) at (NULL for none)
     struct thread_basic_info        m_basicInfo;    // Basic information for a thread used to see if a thread is valid
-    uint32_t                        m_suspendCount; // The current suspend count
+    int32_t                         m_suspendCount; // The current suspend count > 0 means we have suspended m_suspendCount times,
+                                                    //                           < 0 means we have resumed it m_suspendCount times.
     MachException::Data             m_stop_exception; // The best exception that describes why this thread is stopped
     std::auto_ptr<DNBArchProtocol>  m_arch_ap;      // Arch specific information for register state and more
     const DNBRegisterSetInfo *const m_reg_sets;      // Register set information for this thread

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp?rev=135655&r1=135654&r2=135655&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp Wed Jul 20 20:54:41 2011
@@ -321,10 +321,34 @@
     // Update our thread list, because sometimes libdispatch or the kernel
     // will spawn threads while a task is suspended.
     MachThreadList::collection new_threads;
+    
+    // First figure out if we were planning on running only one thread, and if so force that thread to resume.
+    bool run_one_thread;
+    nub_thread_t solo_thread = INVALID_NUB_THREAD;
+    if (thread_actions.GetSize() > 0 
+        && thread_actions.NumActionsWithState(eStateStepping) + thread_actions.NumActionsWithState (eStateRunning) == 1)
+    {
+        run_one_thread = true;
+        const DNBThreadResumeAction *action_ptr = thread_actions.GetFirst();
+        size_t num_actions = thread_actions.GetSize();
+        for (size_t i = 0; i < num_actions; i++, action_ptr++)
+        {
+            if (action_ptr->state == eStateStepping || action_ptr->state == eStateRunning)
+            {
+                solo_thread = action_ptr->tid;
+                break;
+            }
+        }
+    }
+    else
+        run_one_thread = false;
 
     UpdateThreadList(process, true, &new_threads);
 
     DNBThreadResumeAction resume_new_threads = { -1, eStateRunning, 0, INVALID_NUB_ADDRESS };
+    // If we are planning to run only one thread, any new threads should be suspended.
+    if (run_one_thread)
+        resume_new_threads.state = eStateSuspended;
 
     const uint32_t num_new_threads = new_threads.size();
     const uint32_t num_threads = m_threads.size();
@@ -347,7 +371,10 @@
             const DNBThreadResumeAction *thread_action = thread_actions.GetActionForThread (thread->ThreadID(), true);
             // There must always be a thread action for every thread.
             assert (thread_action);
-            thread->ThreadWillResume (thread_action);
+            bool others_stopped = false;
+            if (solo_thread == thread->ThreadID())
+                others_stopped = true;
+            thread->ThreadWillResume (thread_action, others_stopped);
         }
     }
     





More information about the lldb-commits mailing list