[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