parent
009e758628
commit
30df85e67f
|
@ -12,10 +12,6 @@
|
|||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "LinuxThread.h"
|
||||
#include "lldb/Core/State.h"
|
||||
#include "ProcessPOSIX.h"
|
||||
#include "ProcessMonitor.h"
|
||||
#include "ProcessPOSIXLog.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
@ -35,43 +31,6 @@ LinuxThread::~LinuxThread()
|
|||
//------------------------------------------------------------------------------
|
||||
// ProcessInterface protocol.
|
||||
|
||||
bool
|
||||
LinuxThread::Resume()
|
||||
{
|
||||
lldb::StateType resume_state = GetResumeState();
|
||||
ProcessMonitor &monitor = GetMonitor();
|
||||
bool status;
|
||||
|
||||
Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
|
||||
if (log)
|
||||
log->Printf ("POSIXThread::%s (), resume_state = %s", __FUNCTION__,
|
||||
StateAsCString(resume_state));
|
||||
|
||||
switch (resume_state)
|
||||
{
|
||||
default:
|
||||
assert(false && "Unexpected state for resume!");
|
||||
status = false;
|
||||
break;
|
||||
|
||||
case lldb::eStateRunning:
|
||||
SetState(resume_state);
|
||||
status = monitor.Resume(GetID(), GetResumeSignal());
|
||||
break;
|
||||
|
||||
case lldb::eStateStepping:
|
||||
SetState(resume_state);
|
||||
status = monitor.SingleStep(GetID(), GetResumeSignal());
|
||||
break;
|
||||
case lldb::eStateStopped:
|
||||
case lldb::eStateSuspended:
|
||||
status = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
LinuxThread::RefreshStateAfterStop()
|
||||
{
|
||||
|
|
|
@ -31,10 +31,7 @@ public:
|
|||
//--------------------------------------------------------------------------
|
||||
// LinuxThread internal API.
|
||||
|
||||
// POSIXThread overrides
|
||||
virtual bool
|
||||
Resume();
|
||||
|
||||
// POSIXThread override
|
||||
virtual void
|
||||
RefreshStateAfterStop();
|
||||
|
||||
|
|
|
@ -166,31 +166,6 @@ ProcessLinux::DoDetach(bool keep_stopped)
|
|||
|
||||
|
||||
// ProcessPOSIX override
|
||||
Error
|
||||
ProcessLinux::DoResume()
|
||||
{
|
||||
StateType state = GetPrivateState();
|
||||
|
||||
assert(state == eStateStopped);
|
||||
|
||||
SetPrivateState(eStateRunning);
|
||||
|
||||
bool did_resume = false;
|
||||
|
||||
Mutex::Locker lock(m_thread_list.GetMutex());
|
||||
|
||||
uint32_t thread_count = m_thread_list.GetSize(false);
|
||||
for (uint32_t i = 0; i < thread_count; ++i)
|
||||
{
|
||||
LinuxThread *thread = static_cast<LinuxThread*>(
|
||||
m_thread_list.GetThreadAtIndex(i, false).get());
|
||||
did_resume = thread->Resume() || did_resume;
|
||||
}
|
||||
assert(did_resume && "Process resume failed!");
|
||||
|
||||
return Error();
|
||||
}
|
||||
|
||||
void
|
||||
ProcessLinux::StopAllThreads(lldb::tid_t stop_tid)
|
||||
{
|
||||
|
@ -246,103 +221,3 @@ ProcessLinux::CanDebug(Target &target, bool plugin_specified_by_name)
|
|||
return ProcessPOSIX::CanDebug(target, plugin_specified_by_name);
|
||||
}
|
||||
|
||||
void
|
||||
ProcessLinux::SendMessage(const ProcessMessage &message)
|
||||
{
|
||||
Mutex::Locker lock(m_message_mutex);
|
||||
|
||||
Mutex::Locker thread_lock(m_thread_list.GetMutex());
|
||||
|
||||
POSIXThread *thread = static_cast<POSIXThread*>(
|
||||
m_thread_list.FindThreadByID(message.GetTID(), false).get());
|
||||
|
||||
switch (message.GetKind())
|
||||
{
|
||||
case ProcessMessage::eInvalidMessage:
|
||||
return;
|
||||
|
||||
case ProcessMessage::eAttachMessage:
|
||||
SetPrivateState(eStateStopped);
|
||||
return;
|
||||
|
||||
case ProcessMessage::eLimboMessage:
|
||||
assert(thread);
|
||||
thread->SetState(eStateStopped);
|
||||
if (message.GetTID() == GetID())
|
||||
{
|
||||
m_exit_status = message.GetExitStatus();
|
||||
if (m_exit_now)
|
||||
{
|
||||
SetPrivateState(eStateExited);
|
||||
m_monitor->Detach(GetID());
|
||||
}
|
||||
else
|
||||
{
|
||||
StopAllThreads(message.GetTID());
|
||||
SetPrivateState(eStateStopped);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
StopAllThreads(message.GetTID());
|
||||
SetPrivateState(eStateStopped);
|
||||
}
|
||||
break;
|
||||
|
||||
case ProcessMessage::eExitMessage:
|
||||
assert(thread);
|
||||
thread->SetState(eStateExited);
|
||||
// FIXME: I'm not sure we need to do this.
|
||||
if (message.GetTID() == GetID())
|
||||
{
|
||||
m_exit_status = message.GetExitStatus();
|
||||
SetExitStatus(m_exit_status, NULL);
|
||||
}
|
||||
else if (!IsAThreadRunning())
|
||||
SetPrivateState(eStateStopped);
|
||||
break;
|
||||
|
||||
case ProcessMessage::eSignalMessage:
|
||||
case ProcessMessage::eSignalDeliveredMessage:
|
||||
if (message.GetSignal() == SIGSTOP &&
|
||||
AddThreadForInitialStopIfNeeded(message.GetTID()))
|
||||
return;
|
||||
// Intentional fall-through
|
||||
|
||||
case ProcessMessage::eBreakpointMessage:
|
||||
case ProcessMessage::eTraceMessage:
|
||||
case ProcessMessage::eWatchpointMessage:
|
||||
case ProcessMessage::eCrashMessage:
|
||||
assert(thread);
|
||||
thread->SetState(eStateStopped);
|
||||
StopAllThreads(message.GetTID());
|
||||
break;
|
||||
|
||||
case ProcessMessage::eNewThreadMessage:
|
||||
{
|
||||
lldb::tid_t new_tid = message.GetChildTID();
|
||||
if (WaitingForInitialStop(new_tid))
|
||||
{
|
||||
m_monitor->WaitForInitialTIDStop(new_tid);
|
||||
}
|
||||
assert(thread);
|
||||
thread->SetState(eStateStopped);
|
||||
StopAllThreads(message.GetTID());
|
||||
SetPrivateState(eStateStopped);
|
||||
break;
|
||||
}
|
||||
|
||||
case ProcessMessage::eExecMessage:
|
||||
{
|
||||
assert(thread);
|
||||
thread->SetState(eStateStopped);
|
||||
StopAllThreads(message.GetTID());
|
||||
SetPrivateState(eStateStopped);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_message_queue.push(message);
|
||||
}
|
||||
|
||||
|
|
|
@ -60,9 +60,6 @@ public:
|
|||
virtual bool
|
||||
UpdateThreadList(lldb_private::ThreadList &old_thread_list, lldb_private::ThreadList &new_thread_list);
|
||||
|
||||
virtual lldb_private::Error
|
||||
DoResume();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// PluginInterface protocol
|
||||
//------------------------------------------------------------------
|
||||
|
@ -104,9 +101,6 @@ public:
|
|||
virtual POSIXThread *
|
||||
CreateNewPOSIXThread(lldb_private::Process &process, lldb::tid_t tid);
|
||||
|
||||
virtual void
|
||||
SendMessage(const ProcessMessage &message);
|
||||
|
||||
private:
|
||||
|
||||
/// Linux-specific signal set.
|
||||
|
|
|
@ -276,6 +276,43 @@ POSIXThread::DidStop()
|
|||
// Don't set the thread state to stopped unless we really stopped.
|
||||
}
|
||||
|
||||
bool
|
||||
POSIXThread::Resume()
|
||||
{
|
||||
lldb::StateType resume_state = GetResumeState();
|
||||
ProcessMonitor &monitor = GetMonitor();
|
||||
bool status;
|
||||
|
||||
Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
|
||||
if (log)
|
||||
log->Printf ("POSIXThread::%s (), resume_state = %s", __FUNCTION__,
|
||||
StateAsCString(resume_state));
|
||||
|
||||
switch (resume_state)
|
||||
{
|
||||
default:
|
||||
assert(false && "Unexpected state for resume!");
|
||||
status = false;
|
||||
break;
|
||||
|
||||
case lldb::eStateRunning:
|
||||
SetState(resume_state);
|
||||
status = monitor.Resume(GetID(), GetResumeSignal());
|
||||
break;
|
||||
|
||||
case lldb::eStateStepping:
|
||||
SetState(resume_state);
|
||||
status = monitor.SingleStep(GetID(), GetResumeSignal());
|
||||
break;
|
||||
case lldb::eStateStopped:
|
||||
case lldb::eStateSuspended:
|
||||
status = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
POSIXThread::Notify(const ProcessMessage &message)
|
||||
{
|
||||
|
|
|
@ -79,6 +79,8 @@ public:
|
|||
//--------------------------------------------------------------------------
|
||||
// These methods form a specialized interface to POSIX threads.
|
||||
//
|
||||
bool Resume();
|
||||
|
||||
void Notify(const ProcessMessage &message);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
|
|
@ -259,6 +259,31 @@ ProcessPOSIX::DidLaunch()
|
|||
{
|
||||
}
|
||||
|
||||
Error
|
||||
ProcessPOSIX::DoResume()
|
||||
{
|
||||
StateType state = GetPrivateState();
|
||||
|
||||
assert(state == eStateStopped);
|
||||
|
||||
SetPrivateState(eStateRunning);
|
||||
|
||||
bool did_resume = false;
|
||||
|
||||
Mutex::Locker lock(m_thread_list.GetMutex());
|
||||
|
||||
uint32_t thread_count = m_thread_list.GetSize(false);
|
||||
for (uint32_t i = 0; i < thread_count; ++i)
|
||||
{
|
||||
POSIXThread *thread = static_cast<POSIXThread*>(
|
||||
m_thread_list.GetThreadAtIndex(i, false).get());
|
||||
did_resume = thread->Resume() || did_resume;
|
||||
}
|
||||
assert(did_resume && "Process resume failed!");
|
||||
|
||||
return Error();
|
||||
}
|
||||
|
||||
addr_t
|
||||
ProcessPOSIX::GetImageInfoAddress()
|
||||
{
|
||||
|
@ -351,6 +376,107 @@ ProcessPOSIX::DoDidExec()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ProcessPOSIX::SendMessage(const ProcessMessage &message)
|
||||
{
|
||||
Mutex::Locker lock(m_message_mutex);
|
||||
|
||||
Mutex::Locker thread_lock(m_thread_list.GetMutex());
|
||||
|
||||
POSIXThread *thread = static_cast<POSIXThread*>(
|
||||
m_thread_list.FindThreadByID(message.GetTID(), false).get());
|
||||
|
||||
switch (message.GetKind())
|
||||
{
|
||||
case ProcessMessage::eInvalidMessage:
|
||||
return;
|
||||
|
||||
case ProcessMessage::eAttachMessage:
|
||||
SetPrivateState(eStateStopped);
|
||||
return;
|
||||
|
||||
case ProcessMessage::eLimboMessage:
|
||||
assert(thread);
|
||||
thread->SetState(eStateStopped);
|
||||
if (message.GetTID() == GetID())
|
||||
{
|
||||
m_exit_status = message.GetExitStatus();
|
||||
if (m_exit_now)
|
||||
{
|
||||
SetPrivateState(eStateExited);
|
||||
m_monitor->Detach(GetID());
|
||||
}
|
||||
else
|
||||
{
|
||||
StopAllThreads(message.GetTID());
|
||||
SetPrivateState(eStateStopped);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
StopAllThreads(message.GetTID());
|
||||
SetPrivateState(eStateStopped);
|
||||
}
|
||||
break;
|
||||
|
||||
case ProcessMessage::eExitMessage:
|
||||
assert(thread);
|
||||
thread->SetState(eStateExited);
|
||||
// FIXME: I'm not sure we need to do this.
|
||||
if (message.GetTID() == GetID())
|
||||
{
|
||||
m_exit_status = message.GetExitStatus();
|
||||
SetExitStatus(m_exit_status, NULL);
|
||||
}
|
||||
else if (!IsAThreadRunning())
|
||||
SetPrivateState(eStateStopped);
|
||||
break;
|
||||
|
||||
case ProcessMessage::eSignalMessage:
|
||||
case ProcessMessage::eSignalDeliveredMessage:
|
||||
if (message.GetSignal() == SIGSTOP &&
|
||||
AddThreadForInitialStopIfNeeded(message.GetTID()))
|
||||
return;
|
||||
// Intentional fall-through
|
||||
|
||||
case ProcessMessage::eBreakpointMessage:
|
||||
case ProcessMessage::eTraceMessage:
|
||||
case ProcessMessage::eWatchpointMessage:
|
||||
case ProcessMessage::eCrashMessage:
|
||||
assert(thread);
|
||||
thread->SetState(eStateStopped);
|
||||
StopAllThreads(message.GetTID());
|
||||
SetPrivateState(eStateStopped);
|
||||
break;
|
||||
|
||||
case ProcessMessage::eNewThreadMessage:
|
||||
{
|
||||
lldb::tid_t new_tid = message.GetChildTID();
|
||||
if (WaitingForInitialStop(new_tid))
|
||||
{
|
||||
m_monitor->WaitForInitialTIDStop(new_tid);
|
||||
}
|
||||
assert(thread);
|
||||
thread->SetState(eStateStopped);
|
||||
StopAllThreads(message.GetTID());
|
||||
SetPrivateState(eStateStopped);
|
||||
break;
|
||||
}
|
||||
|
||||
case ProcessMessage::eExecMessage:
|
||||
{
|
||||
assert(thread);
|
||||
thread->SetState(eStateStopped);
|
||||
StopAllThreads(message.GetTID());
|
||||
SetPrivateState(eStateStopped);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_message_queue.push(message);
|
||||
}
|
||||
|
||||
void
|
||||
ProcessPOSIX::StopAllThreads(lldb::tid_t stop_tid)
|
||||
{
|
||||
|
|
|
@ -64,7 +64,7 @@ public:
|
|||
DidLaunch();
|
||||
|
||||
virtual lldb_private::Error
|
||||
DoResume() = 0;
|
||||
DoResume();
|
||||
|
||||
virtual lldb_private::Error
|
||||
DoHalt(bool &caused_stop);
|
||||
|
@ -149,7 +149,7 @@ public:
|
|||
|
||||
/// Registers the given message with this process.
|
||||
virtual void
|
||||
SendMessage(const ProcessMessage &message) = 0;
|
||||
SendMessage(const ProcessMessage &message);
|
||||
|
||||
ProcessMonitor &
|
||||
GetMonitor() { assert(m_monitor); return *m_monitor; }
|
||||
|
|
Loading…
Reference in New Issue