forked from OSchip/llvm-project
Reinstating r181091 and r181106 with fix for Linux regressions.
llvm-svn: 181340
This commit is contained in:
parent
6baa776173
commit
ba4e61d3f5
|
@ -65,7 +65,9 @@ public:
|
|||
// Plug-in Methods
|
||||
//------------------------------------------------------------------
|
||||
virtual bool
|
||||
UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list) = 0;
|
||||
UpdateThreadList (ThreadList &old_thread_list,
|
||||
ThreadList &real_thread_list,
|
||||
ThreadList &new_thread_list) = 0;
|
||||
|
||||
virtual void
|
||||
ThreadWasSelected (Thread *thread) = 0;
|
||||
|
|
|
@ -3631,7 +3631,10 @@ protected:
|
|||
std::map<uint64_t, uint32_t> m_thread_id_to_index_id_map;
|
||||
int m_exit_status; ///< The exit status of the process, or -1 if not set.
|
||||
std::string m_exit_string; ///< A textual description of why a process exited.
|
||||
ThreadList m_thread_list; ///< The threads for this process.
|
||||
Mutex m_thread_mutex;
|
||||
ThreadList m_thread_list_real; ///< The threads for this process as are known to the protocol we are debugging with
|
||||
ThreadList m_thread_list; ///< The threads for this process as the user will see them. This is usually the same as
|
||||
///< m_thread_list_real, but might be different if there is an OS plug-in creating memory threads
|
||||
std::vector<Notifications> m_notifications; ///< The list of notifications that this process can deliver.
|
||||
std::vector<lldb::addr_t> m_image_tokens;
|
||||
Listener &m_listener;
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include <vector>
|
||||
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/Host/Mutex.h"
|
||||
#include "lldb/Core/UserID.h"
|
||||
|
||||
|
||||
|
@ -130,10 +129,7 @@ public:
|
|||
SetStopID (uint32_t stop_id);
|
||||
|
||||
Mutex &
|
||||
GetMutex ()
|
||||
{
|
||||
return m_threads_mutex;
|
||||
}
|
||||
GetMutex ();
|
||||
|
||||
void
|
||||
Update (ThreadList &rhs);
|
||||
|
@ -150,7 +146,6 @@ protected:
|
|||
Process *m_process; ///< The process that manages this thread list.
|
||||
uint32_t m_stop_id; ///< The process stop ID that this thread list is valid for.
|
||||
collection m_threads; ///< The threads for this process.
|
||||
mutable Mutex m_threads_mutex;
|
||||
lldb::tid_t m_selected_tid; ///< For targets that need the notion of a current thread.
|
||||
|
||||
private:
|
||||
|
|
|
@ -171,7 +171,9 @@ OperatingSystemPython::GetPluginVersion()
|
|||
}
|
||||
|
||||
bool
|
||||
OperatingSystemPython::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
|
||||
OperatingSystemPython::UpdateThreadList (ThreadList &old_thread_list,
|
||||
ThreadList &core_thread_list,
|
||||
ThreadList &new_thread_list)
|
||||
{
|
||||
if (!m_interpreter || !m_python_object_sp)
|
||||
return false;
|
||||
|
@ -194,8 +196,6 @@ OperatingSystemPython::UpdateThreadList (ThreadList &old_thread_list, ThreadList
|
|||
PythonList threads_list(m_interpreter->OSPlugin_ThreadsInfo(m_python_object_sp));
|
||||
if (threads_list)
|
||||
{
|
||||
ThreadList core_thread_list(new_thread_list);
|
||||
|
||||
uint32_t i;
|
||||
const uint32_t num_threads = threads_list.GetSize();
|
||||
for (i=0; i<num_threads; ++i)
|
||||
|
|
|
@ -65,7 +65,8 @@ public:
|
|||
// lldb_private::OperatingSystem Methods
|
||||
//------------------------------------------------------------------
|
||||
virtual bool
|
||||
UpdateThreadList (lldb_private::ThreadList &old_thread_list,
|
||||
UpdateThreadList (lldb_private::ThreadList &old_thread_list,
|
||||
lldb_private::ThreadList &real_thread_list,
|
||||
lldb_private::ThreadList &new_thread_list);
|
||||
|
||||
virtual void
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
static const lldb::tid_t g_kernel_tid = 1;
|
||||
|
||||
const char *
|
||||
ProcessKDP::GetPluginNameStatic()
|
||||
{
|
||||
|
@ -116,7 +118,8 @@ ProcessKDP::ProcessKDP(Target& target, Listener &listener) :
|
|||
m_async_thread (LLDB_INVALID_HOST_THREAD),
|
||||
m_dyld_plugin_name (),
|
||||
m_kernel_load_addr (LLDB_INVALID_ADDRESS),
|
||||
m_command_sp()
|
||||
m_command_sp(),
|
||||
m_kernel_thread_wp()
|
||||
{
|
||||
m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit");
|
||||
m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue, "async thread continue");
|
||||
|
@ -377,7 +380,8 @@ ProcessKDP::DoResume ()
|
|||
bool resume = false;
|
||||
|
||||
// With KDP there is only one thread we can tell what to do
|
||||
ThreadSP kernel_thread_sp (GetKernelThread(m_thread_list, m_thread_list));
|
||||
ThreadSP kernel_thread_sp (m_thread_list.FindThreadByProtocolID(g_kernel_tid));
|
||||
|
||||
if (kernel_thread_sp)
|
||||
{
|
||||
const StateType thread_resume_state = kernel_thread_sp->GetTemporaryResumeState();
|
||||
|
@ -449,15 +453,17 @@ ProcessKDP::DoResume ()
|
|||
}
|
||||
|
||||
lldb::ThreadSP
|
||||
ProcessKDP::GetKernelThread(ThreadList &old_thread_list, ThreadList &new_thread_list)
|
||||
ProcessKDP::GetKernelThread()
|
||||
{
|
||||
// KDP only tells us about one thread/core. Any other threads will usually
|
||||
// be the ones that are read from memory by the OS plug-ins.
|
||||
const lldb::tid_t kernel_tid = 1;
|
||||
ThreadSP thread_sp (old_thread_list.FindThreadByID (kernel_tid, false));
|
||||
|
||||
ThreadSP thread_sp (m_kernel_thread_wp.lock());
|
||||
if (!thread_sp)
|
||||
thread_sp.reset(new ThreadKDP (*this, kernel_tid));
|
||||
new_thread_list.AddThread(thread_sp);
|
||||
{
|
||||
thread_sp.reset(new ThreadKDP (*this, g_kernel_tid));
|
||||
m_kernel_thread_wp = thread_sp;
|
||||
}
|
||||
return thread_sp;
|
||||
}
|
||||
|
||||
|
@ -474,7 +480,10 @@ ProcessKDP::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_threa
|
|||
|
||||
// Even though there is a CPU mask, it doesn't mean we can see each CPU
|
||||
// indivudually, there is really only one. Lets call this thread 1.
|
||||
GetKernelThread (old_thread_list, new_thread_list);
|
||||
ThreadSP thread_sp (old_thread_list.FindThreadByProtocolID(g_kernel_tid, false));
|
||||
if (!thread_sp)
|
||||
thread_sp = GetKernelThread ();
|
||||
new_thread_list.AddThread(thread_sp);
|
||||
|
||||
return new_thread_list.GetSize(false) > 0;
|
||||
}
|
||||
|
@ -798,7 +807,7 @@ ProcessKDP::AsyncThread (void *arg)
|
|||
is_running = true;
|
||||
if (process->m_comm.WaitForPacketWithTimeoutMicroSeconds (exc_reply_packet, 1 * USEC_PER_SEC))
|
||||
{
|
||||
ThreadSP thread_sp (process->GetKernelThread(process->GetThreadList(), process->GetThreadList()));
|
||||
ThreadSP thread_sp (process->GetKernelThread());
|
||||
if (thread_sp)
|
||||
{
|
||||
lldb::RegisterContextSP reg_ctx_sp (thread_sp->GetRegisterContext());
|
||||
|
|
|
@ -225,12 +225,6 @@ protected:
|
|||
bool
|
||||
ProcessIDIsValid ( ) const;
|
||||
|
||||
// static void
|
||||
// STDIOReadThreadBytesReceived (void *baton, const void *src, size_t src_len);
|
||||
|
||||
// void
|
||||
// AppendSTDOUT (const char* s, size_t len);
|
||||
|
||||
void
|
||||
Clear ( );
|
||||
|
||||
|
@ -245,8 +239,7 @@ protected:
|
|||
};
|
||||
|
||||
lldb::ThreadSP
|
||||
GetKernelThread (lldb_private::ThreadList &old_thread_list,
|
||||
lldb_private::ThreadList &new_thread_list);
|
||||
GetKernelThread ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Broadcaster event bits definitions.
|
||||
|
@ -257,6 +250,7 @@ protected:
|
|||
std::string m_dyld_plugin_name;
|
||||
lldb::addr_t m_kernel_load_addr;
|
||||
lldb::CommandObjectSP m_command_sp;
|
||||
lldb::ThreadWP m_kernel_thread_wp;
|
||||
|
||||
|
||||
bool
|
||||
|
|
|
@ -140,7 +140,7 @@ POSIXThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame)
|
|||
lldb::StopInfoSP
|
||||
POSIXThread::GetPrivateStopReason()
|
||||
{
|
||||
return m_stop_info;
|
||||
return m_actual_stop_info_sp;
|
||||
}
|
||||
|
||||
Unwind *
|
||||
|
@ -262,19 +262,19 @@ POSIXThread::BreakNotify(const ProcessMessage &message)
|
|||
|
||||
|
||||
m_breakpoint = bp_site;
|
||||
m_stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id);
|
||||
SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id));
|
||||
}
|
||||
|
||||
void
|
||||
POSIXThread::TraceNotify(const ProcessMessage &message)
|
||||
{
|
||||
m_stop_info = StopInfo::CreateStopReasonToTrace(*this);
|
||||
SetStopInfo (StopInfo::CreateStopReasonToTrace(*this));
|
||||
}
|
||||
|
||||
void
|
||||
POSIXThread::LimboNotify(const ProcessMessage &message)
|
||||
{
|
||||
m_stop_info = lldb::StopInfoSP(new POSIXLimboStopInfo(*this));
|
||||
SetStopInfo (lldb::StopInfoSP(new POSIXLimboStopInfo(*this)));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -282,7 +282,7 @@ POSIXThread::SignalNotify(const ProcessMessage &message)
|
|||
{
|
||||
int signo = message.GetSignal();
|
||||
|
||||
m_stop_info = StopInfo::CreateStopReasonWithSignal(*this, signo);
|
||||
SetStopInfo (StopInfo::CreateStopReasonWithSignal(*this, signo));
|
||||
SetResumeSignal(signo);
|
||||
}
|
||||
|
||||
|
@ -291,7 +291,7 @@ POSIXThread::SignalDeliveredNotify(const ProcessMessage &message)
|
|||
{
|
||||
int signo = message.GetSignal();
|
||||
|
||||
m_stop_info = StopInfo::CreateStopReasonWithSignal(*this, signo);
|
||||
SetStopInfo (StopInfo::CreateStopReasonWithSignal(*this, signo));
|
||||
SetResumeSignal(signo);
|
||||
}
|
||||
|
||||
|
@ -306,15 +306,14 @@ POSIXThread::CrashNotify(const ProcessMessage &message)
|
|||
if (log)
|
||||
log->Printf ("POSIXThread::%s () signo = %i, reason = '%s'", __FUNCTION__, signo, message.PrintCrashReason());
|
||||
|
||||
m_stop_info = lldb::StopInfoSP(new POSIXCrashStopInfo(
|
||||
*this, signo, message.GetCrashReason()));
|
||||
SetStopInfo (lldb::StopInfoSP(new POSIXCrashStopInfo(*this, signo, message.GetCrashReason())));
|
||||
SetResumeSignal(signo);
|
||||
}
|
||||
|
||||
void
|
||||
POSIXThread::ThreadNotify(const ProcessMessage &message)
|
||||
{
|
||||
m_stop_info = lldb::StopInfoSP(new POSIXNewThreadStopInfo(*this));
|
||||
SetStopInfo (lldb::StopInfoSP(new POSIXNewThreadStopInfo(*this)));
|
||||
}
|
||||
|
||||
unsigned
|
||||
|
|
|
@ -84,7 +84,6 @@ private:
|
|||
std::unique_ptr<lldb_private::StackFrame> m_frame_ap;
|
||||
|
||||
lldb::BreakpointSiteSP m_breakpoint;
|
||||
lldb::StopInfoSP m_stop_info;
|
||||
|
||||
ProcessMonitor &
|
||||
GetMonitor();
|
||||
|
|
|
@ -1281,14 +1281,14 @@ ProcessGDBRemote::DoResume ()
|
|||
void
|
||||
ProcessGDBRemote::ClearThreadIDList ()
|
||||
{
|
||||
Mutex::Locker locker(m_thread_list.GetMutex());
|
||||
Mutex::Locker locker(m_thread_list_real.GetMutex());
|
||||
m_thread_ids.clear();
|
||||
}
|
||||
|
||||
bool
|
||||
ProcessGDBRemote::UpdateThreadIDList ()
|
||||
{
|
||||
Mutex::Locker locker(m_thread_list.GetMutex());
|
||||
Mutex::Locker locker(m_thread_list_real.GetMutex());
|
||||
bool sequence_mutex_unavailable = false;
|
||||
m_gdb_comm.GetCurrentThreadIDs (m_thread_ids, sequence_mutex_unavailable);
|
||||
if (sequence_mutex_unavailable)
|
||||
|
@ -1323,12 +1323,6 @@ ProcessGDBRemote::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new
|
|||
{
|
||||
tid_t tid = m_thread_ids[i];
|
||||
ThreadSP thread_sp (old_thread_list_copy.RemoveThreadByProtocolID(tid, false));
|
||||
if (thread_sp)
|
||||
{
|
||||
ThreadSP backing_thread_sp (thread_sp->GetBackingThread());
|
||||
if (backing_thread_sp && backing_thread_sp->GetProtocolID() == tid)
|
||||
thread_sp = backing_thread_sp;
|
||||
}
|
||||
if (!thread_sp)
|
||||
thread_sp.reset (new ThreadGDBRemote (*this, tid));
|
||||
new_thread_list.AddThread(thread_sp);
|
||||
|
@ -1385,7 +1379,6 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
|
|||
std::vector<addr_t> exc_data;
|
||||
addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS;
|
||||
ThreadSP thread_sp;
|
||||
ThreadSP backing_thread_sp;
|
||||
ThreadGDBRemote *gdb_thread = NULL;
|
||||
|
||||
while (stop_packet.GetNameColonValue(name, value))
|
||||
|
@ -1404,31 +1397,24 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
|
|||
{
|
||||
// thread in big endian hex
|
||||
lldb::tid_t tid = Args::StringToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
|
||||
// m_thread_list does have its own mutex, but we need to
|
||||
// hold onto the mutex between the call to m_thread_list.FindThreadByID(...)
|
||||
// and the m_thread_list.AddThread(...) so it doesn't change on us
|
||||
Mutex::Locker locker (m_thread_list.GetMutex ());
|
||||
thread_sp = m_thread_list.FindThreadByProtocolID(tid, false);
|
||||
// m_thread_list_real does have its own mutex, but we need to
|
||||
// hold onto the mutex between the call to m_thread_list_real.FindThreadByID(...)
|
||||
// and the m_thread_list_real.AddThread(...) so it doesn't change on us
|
||||
Mutex::Locker locker (m_thread_list_real.GetMutex ());
|
||||
thread_sp = m_thread_list_real.FindThreadByProtocolID(tid, false);
|
||||
|
||||
if (thread_sp)
|
||||
{
|
||||
backing_thread_sp = thread_sp->GetBackingThread();
|
||||
if (backing_thread_sp)
|
||||
gdb_thread = static_cast<ThreadGDBRemote *> (backing_thread_sp.get());
|
||||
else
|
||||
gdb_thread = static_cast<ThreadGDBRemote *> (thread_sp.get());
|
||||
}
|
||||
else
|
||||
if (!thread_sp)
|
||||
{
|
||||
// Create the thread if we need to
|
||||
thread_sp.reset (new ThreadGDBRemote (*this, tid));
|
||||
gdb_thread = static_cast<ThreadGDBRemote *> (thread_sp.get());
|
||||
m_thread_list.AddThread(thread_sp);
|
||||
m_thread_list_real.AddThread(thread_sp);
|
||||
}
|
||||
gdb_thread = static_cast<ThreadGDBRemote *> (thread_sp.get());
|
||||
|
||||
}
|
||||
else if (name.compare("threads") == 0)
|
||||
{
|
||||
Mutex::Locker locker(m_thread_list.GetMutex());
|
||||
Mutex::Locker locker(m_thread_list_real.GetMutex());
|
||||
m_thread_ids.clear();
|
||||
// A comma separated list of all threads in the current
|
||||
// process that includes the thread for this stop reply
|
||||
|
@ -1508,6 +1494,9 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
|
|||
|
||||
if (thread_sp)
|
||||
{
|
||||
// Clear the stop info just in case we don't set it to anything
|
||||
thread_sp->SetStopInfo (StopInfoSP());
|
||||
|
||||
gdb_thread->SetThreadDispatchQAddr (thread_dispatch_qaddr);
|
||||
gdb_thread->SetName (thread_name.empty() ? NULL : thread_name.c_str());
|
||||
if (exc_type != 0)
|
||||
|
@ -1610,11 +1599,6 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
|
|||
if (!handled)
|
||||
thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithSignal (*thread_sp, signo));
|
||||
}
|
||||
else
|
||||
{
|
||||
StopInfoSP invalid_stop_info_sp;
|
||||
thread_sp->SetStopInfo (invalid_stop_info_sp);
|
||||
}
|
||||
|
||||
if (!description.empty())
|
||||
{
|
||||
|
@ -1647,7 +1631,7 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
|
|||
void
|
||||
ProcessGDBRemote::RefreshStateAfterStop ()
|
||||
{
|
||||
Mutex::Locker locker(m_thread_list.GetMutex());
|
||||
Mutex::Locker locker(m_thread_list_real.GetMutex());
|
||||
m_thread_ids.clear();
|
||||
// Set the thread stop info. It might have a "threads" key whose value is
|
||||
// a list of all thread IDs in the current process, so m_thread_ids might
|
||||
|
@ -1662,7 +1646,7 @@ ProcessGDBRemote::RefreshStateAfterStop ()
|
|||
|
||||
// Let all threads recover from stopping and do any clean up based
|
||||
// on the previous thread state (if any).
|
||||
m_thread_list.RefreshStateAfterStop();
|
||||
m_thread_list_real.RefreshStateAfterStop();
|
||||
|
||||
}
|
||||
|
||||
|
@ -2330,6 +2314,7 @@ void
|
|||
ProcessGDBRemote::Clear()
|
||||
{
|
||||
m_flags = 0;
|
||||
m_thread_list_real.Clear();
|
||||
m_thread_list.Clear();
|
||||
}
|
||||
|
||||
|
|
|
@ -204,27 +204,46 @@ ThreadGDBRemote::GetPrivateStopReason ()
|
|||
if (process_sp)
|
||||
{
|
||||
const uint32_t process_stop_id = process_sp->GetStopID();
|
||||
if (m_thread_stop_reason_stop_id != process_stop_id ||
|
||||
(m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
|
||||
if (m_thread_stop_reason_stop_id == process_stop_id)
|
||||
{
|
||||
// Our stop info is up to date even if it is empty...
|
||||
return m_actual_stop_info_sp;
|
||||
}
|
||||
|
||||
if (m_actual_stop_info_sp && m_actual_stop_info_sp->IsValid())
|
||||
{
|
||||
// The stop info is up to date, reset it so everything updates
|
||||
SetStopInfo (m_actual_stop_info_sp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsStillAtLastBreakpointHit())
|
||||
return m_actual_stop_info_sp;
|
||||
{
|
||||
SetStopInfo(m_actual_stop_info_sp);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If GetGDBProcess().SetThreadStopInfo() doesn't find a stop reason
|
||||
// for this thread, then m_actual_stop_info_sp will not ever contain
|
||||
// a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
|
||||
// check will never be able to tell us if we have the correct stop info
|
||||
// for this thread and we will continually send qThreadStopInfo packets
|
||||
// down to the remote GDB server, so we need to keep our own notion
|
||||
// of the stop ID that m_actual_stop_info_sp is valid for (even if it
|
||||
// contains nothing). We use m_thread_stop_reason_stop_id for this below.
|
||||
m_actual_stop_info_sp.reset();
|
||||
|
||||
// If GetGDBProcess().SetThreadStopInfo() doesn't find a stop reason
|
||||
// for this thread, then m_actual_stop_info_sp will not ever contain
|
||||
// a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
|
||||
// check will never be able to tell us if we have the correct stop info
|
||||
// for this thread and we will continually send qThreadStopInfo packets
|
||||
// down to the remote GDB server, so we need to keep our own notion
|
||||
// of the stop ID that m_actual_stop_info_sp is valid for (even if it
|
||||
// contains nothing). We use m_thread_stop_reason_stop_id for this below.
|
||||
m_thread_stop_reason_stop_id = process_stop_id;
|
||||
m_actual_stop_info_sp.reset();
|
||||
|
||||
StringExtractorGDBRemote stop_packet;
|
||||
ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get());
|
||||
if (gdb_process->GetGDBRemote().GetThreadStopInfo(GetProtocolID(), stop_packet))
|
||||
gdb_process->SetThreadStopInfo (stop_packet);
|
||||
StringExtractorGDBRemote stop_packet;
|
||||
ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get());
|
||||
if (gdb_process->GetGDBRemote().GetThreadStopInfo(GetProtocolID(), stop_packet))
|
||||
{
|
||||
gdb_process->SetThreadStopInfo (stop_packet);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetStopInfo (StopInfoSP());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return m_actual_stop_info_sp;
|
||||
|
|
|
@ -1016,6 +1016,8 @@ Process::Process(Target &target, Listener &listener) :
|
|||
m_thread_id_to_index_id_map (),
|
||||
m_exit_status (-1),
|
||||
m_exit_string (),
|
||||
m_thread_mutex (Mutex::eMutexTypeRecursive),
|
||||
m_thread_list_real (this),
|
||||
m_thread_list (this),
|
||||
m_notifications (),
|
||||
m_image_tokens (),
|
||||
|
@ -1140,6 +1142,7 @@ Process::Finalize()
|
|||
m_abi_sp.reset();
|
||||
m_os_ap.reset();
|
||||
m_dyld_ap.reset();
|
||||
m_thread_list_real.Destroy();
|
||||
m_thread_list.Destroy();
|
||||
std::vector<Notifications> empty_notifications;
|
||||
m_notifications.swap(empty_notifications);
|
||||
|
@ -1537,10 +1540,12 @@ Process::UpdateThreadListIfNeeded ()
|
|||
// m_thread_list does have its own mutex, but we need to
|
||||
// hold onto the mutex between the call to UpdateThreadList(...)
|
||||
// and the os->UpdateThreadList(...) so it doesn't change on us
|
||||
ThreadList &old_thread_list = m_thread_list;
|
||||
ThreadList real_thread_list(this);
|
||||
ThreadList new_thread_list(this);
|
||||
// Always update the thread list with the protocol specific
|
||||
// thread list, but only update if "true" is returned
|
||||
if (UpdateThreadList (m_thread_list, new_thread_list))
|
||||
if (UpdateThreadList (m_thread_list_real, real_thread_list))
|
||||
{
|
||||
// Don't call into the OperatingSystem to update the thread list if we are shutting down, since
|
||||
// that may call back into the SBAPI's, requiring the API lock which is already held by whoever is
|
||||
|
@ -1552,16 +1557,23 @@ Process::UpdateThreadListIfNeeded ()
|
|||
{
|
||||
// Clear any old backing threads where memory threads might have been
|
||||
// backed by actual threads from the lldb_private::Process subclass
|
||||
size_t num_old_threads = m_thread_list.GetSize(false);
|
||||
size_t num_old_threads = old_thread_list.GetSize(false);
|
||||
for (size_t i=0; i<num_old_threads; ++i)
|
||||
m_thread_list.GetThreadAtIndex(i, false)->ClearBackingThread();
|
||||
old_thread_list.GetThreadAtIndex(i, false)->ClearBackingThread();
|
||||
|
||||
// Now let the OperatingSystem plug-in update the thread list
|
||||
os->UpdateThreadList (m_thread_list, new_thread_list);
|
||||
os->UpdateThreadList (old_thread_list, // Old list full of threads created by OS plug-in
|
||||
real_thread_list, // The actual thread list full of threads created by each lldb_private::Process subclass
|
||||
new_thread_list); // The new thread list that we will show to the user that gets filled in
|
||||
}
|
||||
else
|
||||
{
|
||||
// No OS plug-in, the new thread list is the same as the real thread list
|
||||
new_thread_list = real_thread_list;
|
||||
}
|
||||
m_thread_list.Update (new_thread_list);
|
||||
m_thread_list.SetStopID (stop_id);
|
||||
}
|
||||
m_thread_list.Update (new_thread_list);
|
||||
m_thread_list.SetStopID (stop_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -357,18 +357,24 @@ lldb::StopInfoSP
|
|||
Thread::GetStopInfo ()
|
||||
{
|
||||
ThreadPlanSP plan_sp (GetCompletedPlan());
|
||||
ProcessSP process_sp (GetProcess());
|
||||
const uint32_t stop_id = process_sp ? process_sp->GetStopID() : UINT32_MAX;
|
||||
if (plan_sp && plan_sp->PlanSucceeded())
|
||||
{
|
||||
return StopInfo::CreateStopReasonWithPlan (plan_sp, GetReturnValueObject());
|
||||
}
|
||||
else
|
||||
{
|
||||
ProcessSP process_sp (GetProcess());
|
||||
if (process_sp
|
||||
&& m_actual_stop_info_sp
|
||||
&& m_actual_stop_info_sp->IsValid()
|
||||
&& m_thread_stop_reason_stop_id == process_sp->GetStopID())
|
||||
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
|
||||
{
|
||||
return m_actual_stop_info_sp;
|
||||
}
|
||||
else
|
||||
return GetPrivateStopReason ();
|
||||
{
|
||||
GetPrivateStopReason ();
|
||||
return m_actual_stop_info_sp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,16 +24,14 @@ ThreadList::ThreadList (Process *process) :
|
|||
m_process (process),
|
||||
m_stop_id (0),
|
||||
m_threads(),
|
||||
m_threads_mutex (Mutex::eMutexTypeRecursive),
|
||||
m_selected_tid (LLDB_INVALID_THREAD_ID)
|
||||
{
|
||||
}
|
||||
|
||||
ThreadList::ThreadList (const ThreadList &rhs) :
|
||||
m_process (),
|
||||
m_stop_id (),
|
||||
m_process (rhs.m_process),
|
||||
m_stop_id (rhs.m_stop_id),
|
||||
m_threads (),
|
||||
m_threads_mutex (Mutex::eMutexTypeRecursive),
|
||||
m_selected_tid ()
|
||||
{
|
||||
// Use the assignment operator since it uses the mutex
|
||||
|
@ -47,8 +45,7 @@ ThreadList::operator = (const ThreadList& rhs)
|
|||
{
|
||||
// Lock both mutexes to make sure neither side changes anyone on us
|
||||
// while the assignement occurs
|
||||
Mutex::Locker locker_lhs(m_threads_mutex);
|
||||
Mutex::Locker locker_rhs(rhs.m_threads_mutex);
|
||||
Mutex::Locker locker(GetMutex());
|
||||
m_process = rhs.m_process;
|
||||
m_stop_id = rhs.m_stop_id;
|
||||
m_threads = rhs.m_threads;
|
||||
|
@ -83,14 +80,14 @@ ThreadList::SetStopID (uint32_t stop_id)
|
|||
void
|
||||
ThreadList::AddThread (const ThreadSP &thread_sp)
|
||||
{
|
||||
Mutex::Locker locker(m_threads_mutex);
|
||||
Mutex::Locker locker(GetMutex());
|
||||
m_threads.push_back(thread_sp);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ThreadList::GetSize (bool can_update)
|
||||
{
|
||||
Mutex::Locker locker(m_threads_mutex);
|
||||
Mutex::Locker locker(GetMutex());
|
||||
if (can_update)
|
||||
m_process->UpdateThreadListIfNeeded();
|
||||
return m_threads.size();
|
||||
|
@ -99,7 +96,7 @@ ThreadList::GetSize (bool can_update)
|
|||
ThreadSP
|
||||
ThreadList::GetThreadAtIndex (uint32_t idx, bool can_update)
|
||||
{
|
||||
Mutex::Locker locker(m_threads_mutex);
|
||||
Mutex::Locker locker(GetMutex());
|
||||
if (can_update)
|
||||
m_process->UpdateThreadListIfNeeded();
|
||||
|
||||
|
@ -112,7 +109,7 @@ ThreadList::GetThreadAtIndex (uint32_t idx, bool can_update)
|
|||
ThreadSP
|
||||
ThreadList::FindThreadByID (lldb::tid_t tid, bool can_update)
|
||||
{
|
||||
Mutex::Locker locker(m_threads_mutex);
|
||||
Mutex::Locker locker(GetMutex());
|
||||
|
||||
if (can_update)
|
||||
m_process->UpdateThreadListIfNeeded();
|
||||
|
@ -134,7 +131,7 @@ ThreadList::FindThreadByID (lldb::tid_t tid, bool can_update)
|
|||
ThreadSP
|
||||
ThreadList::FindThreadByProtocolID (lldb::tid_t tid, bool can_update)
|
||||
{
|
||||
Mutex::Locker locker(m_threads_mutex);
|
||||
Mutex::Locker locker(GetMutex());
|
||||
|
||||
if (can_update)
|
||||
m_process->UpdateThreadListIfNeeded();
|
||||
|
@ -157,7 +154,7 @@ ThreadList::FindThreadByProtocolID (lldb::tid_t tid, bool can_update)
|
|||
ThreadSP
|
||||
ThreadList::RemoveThreadByID (lldb::tid_t tid, bool can_update)
|
||||
{
|
||||
Mutex::Locker locker(m_threads_mutex);
|
||||
Mutex::Locker locker(GetMutex());
|
||||
|
||||
if (can_update)
|
||||
m_process->UpdateThreadListIfNeeded();
|
||||
|
@ -180,7 +177,7 @@ ThreadList::RemoveThreadByID (lldb::tid_t tid, bool can_update)
|
|||
ThreadSP
|
||||
ThreadList::RemoveThreadByProtocolID (lldb::tid_t tid, bool can_update)
|
||||
{
|
||||
Mutex::Locker locker(m_threads_mutex);
|
||||
Mutex::Locker locker(GetMutex());
|
||||
|
||||
if (can_update)
|
||||
m_process->UpdateThreadListIfNeeded();
|
||||
|
@ -206,7 +203,7 @@ ThreadList::GetThreadSPForThreadPtr (Thread *thread_ptr)
|
|||
ThreadSP thread_sp;
|
||||
if (thread_ptr)
|
||||
{
|
||||
Mutex::Locker locker(m_threads_mutex);
|
||||
Mutex::Locker locker(GetMutex());
|
||||
|
||||
uint32_t idx = 0;
|
||||
const uint32_t num_threads = m_threads.size();
|
||||
|
@ -227,7 +224,7 @@ ThreadList::GetThreadSPForThreadPtr (Thread *thread_ptr)
|
|||
ThreadSP
|
||||
ThreadList::FindThreadByIndexID (uint32_t index_id, bool can_update)
|
||||
{
|
||||
Mutex::Locker locker(m_threads_mutex);
|
||||
Mutex::Locker locker(GetMutex());
|
||||
|
||||
if (can_update)
|
||||
m_process->UpdateThreadListIfNeeded();
|
||||
|
@ -263,7 +260,7 @@ ThreadList::ShouldStop (Event *event_ptr)
|
|||
collection threads_copy;
|
||||
{
|
||||
// Scope for locker
|
||||
Mutex::Locker locker(m_threads_mutex);
|
||||
Mutex::Locker locker(GetMutex());
|
||||
|
||||
m_process->UpdateThreadListIfNeeded();
|
||||
threads_copy = m_threads;
|
||||
|
@ -331,7 +328,7 @@ ThreadList::ShouldStop (Event *event_ptr)
|
|||
Vote
|
||||
ThreadList::ShouldReportStop (Event *event_ptr)
|
||||
{
|
||||
Mutex::Locker locker(m_threads_mutex);
|
||||
Mutex::Locker locker(GetMutex());
|
||||
|
||||
Vote result = eVoteNoOpinion;
|
||||
m_process->UpdateThreadListIfNeeded();
|
||||
|
@ -383,7 +380,7 @@ Vote
|
|||
ThreadList::ShouldReportRun (Event *event_ptr)
|
||||
{
|
||||
|
||||
Mutex::Locker locker(m_threads_mutex);
|
||||
Mutex::Locker locker(GetMutex());
|
||||
|
||||
Vote result = eVoteNoOpinion;
|
||||
m_process->UpdateThreadListIfNeeded();
|
||||
|
@ -422,7 +419,7 @@ ThreadList::ShouldReportRun (Event *event_ptr)
|
|||
void
|
||||
ThreadList::Clear()
|
||||
{
|
||||
Mutex::Locker locker(m_threads_mutex);
|
||||
Mutex::Locker locker(GetMutex());
|
||||
m_stop_id = 0;
|
||||
m_threads.clear();
|
||||
m_selected_tid = LLDB_INVALID_THREAD_ID;
|
||||
|
@ -431,7 +428,7 @@ ThreadList::Clear()
|
|||
void
|
||||
ThreadList::Destroy()
|
||||
{
|
||||
Mutex::Locker locker(m_threads_mutex);
|
||||
Mutex::Locker locker(GetMutex());
|
||||
const uint32_t num_threads = m_threads.size();
|
||||
for (uint32_t idx = 0; idx < num_threads; ++idx)
|
||||
{
|
||||
|
@ -442,7 +439,7 @@ ThreadList::Destroy()
|
|||
void
|
||||
ThreadList::RefreshStateAfterStop ()
|
||||
{
|
||||
Mutex::Locker locker(m_threads_mutex);
|
||||
Mutex::Locker locker(GetMutex());
|
||||
|
||||
m_process->UpdateThreadListIfNeeded();
|
||||
|
||||
|
@ -460,7 +457,7 @@ ThreadList::DiscardThreadPlans ()
|
|||
{
|
||||
// You don't need to update the thread list here, because only threads
|
||||
// that you currently know about have any thread plans.
|
||||
Mutex::Locker locker(m_threads_mutex);
|
||||
Mutex::Locker locker(GetMutex());
|
||||
|
||||
collection::iterator pos, end = m_threads.end();
|
||||
for (pos = m_threads.begin(); pos != end; ++pos)
|
||||
|
@ -475,7 +472,7 @@ ThreadList::WillResume ()
|
|||
// But we only do this for threads that are running, user suspended
|
||||
// threads stay where they are.
|
||||
|
||||
Mutex::Locker locker(m_threads_mutex);
|
||||
Mutex::Locker locker(GetMutex());
|
||||
m_process->UpdateThreadListIfNeeded();
|
||||
|
||||
collection::iterator pos, end = m_threads.end();
|
||||
|
@ -626,7 +623,7 @@ ThreadList::WillResume ()
|
|||
void
|
||||
ThreadList::DidResume ()
|
||||
{
|
||||
Mutex::Locker locker(m_threads_mutex);
|
||||
Mutex::Locker locker(GetMutex());
|
||||
collection::iterator pos, end = m_threads.end();
|
||||
for (pos = m_threads.begin(); pos != end; ++pos)
|
||||
{
|
||||
|
@ -641,7 +638,7 @@ ThreadList::DidResume ()
|
|||
ThreadSP
|
||||
ThreadList::GetSelectedThread ()
|
||||
{
|
||||
Mutex::Locker locker(m_threads_mutex);
|
||||
Mutex::Locker locker(GetMutex());
|
||||
ThreadSP thread_sp = FindThreadByID(m_selected_tid);
|
||||
if (!thread_sp.get())
|
||||
{
|
||||
|
@ -656,7 +653,7 @@ ThreadList::GetSelectedThread ()
|
|||
bool
|
||||
ThreadList::SetSelectedThreadByID (lldb::tid_t tid, bool notify)
|
||||
{
|
||||
Mutex::Locker locker(m_threads_mutex);
|
||||
Mutex::Locker locker(GetMutex());
|
||||
ThreadSP selected_thread_sp(FindThreadByID(tid));
|
||||
if (selected_thread_sp)
|
||||
{
|
||||
|
@ -675,7 +672,7 @@ ThreadList::SetSelectedThreadByID (lldb::tid_t tid, bool notify)
|
|||
bool
|
||||
ThreadList::SetSelectedThreadByIndexID (uint32_t index_id, bool notify)
|
||||
{
|
||||
Mutex::Locker locker(m_threads_mutex);
|
||||
Mutex::Locker locker(GetMutex());
|
||||
ThreadSP selected_thread_sp (FindThreadByIndexID(index_id));
|
||||
if (selected_thread_sp.get())
|
||||
{
|
||||
|
@ -707,8 +704,7 @@ ThreadList::Update (ThreadList &rhs)
|
|||
{
|
||||
// Lock both mutexes to make sure neither side changes anyone on us
|
||||
// while the assignement occurs
|
||||
Mutex::Locker locker_lhs(m_threads_mutex);
|
||||
Mutex::Locker locker_rhs(rhs.m_threads_mutex);
|
||||
Mutex::Locker locker(GetMutex());
|
||||
m_process = rhs.m_process;
|
||||
m_stop_id = rhs.m_stop_id;
|
||||
m_threads.swap(rhs.m_threads);
|
||||
|
@ -745,9 +741,15 @@ ThreadList::Update (ThreadList &rhs)
|
|||
void
|
||||
ThreadList::Flush ()
|
||||
{
|
||||
Mutex::Locker locker(m_threads_mutex);
|
||||
Mutex::Locker locker(GetMutex());
|
||||
collection::iterator pos, end = m_threads.end();
|
||||
for (pos = m_threads.begin(); pos != end; ++pos)
|
||||
(*pos)->Flush ();
|
||||
}
|
||||
|
||||
Mutex &
|
||||
ThreadList::GetMutex ()
|
||||
{
|
||||
return m_process->m_thread_mutex;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue