diff options
author | Greg Clayton <gclayton@apple.com> | 2013-05-04 01:38:48 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2013-05-04 01:38:48 +0000 |
commit | 1b7746e383ca68d09974947eeca6c17bb132a46a (patch) | |
tree | 53186b955d465615e149dbb60b4c29ca17135d8b | |
parent | cd410d04dbeb373f0762b167b2a202746e8a8eaf (diff) | |
download | bcm5719-llvm-1b7746e383ca68d09974947eeca6c17bb132a46a.tar.gz bcm5719-llvm-1b7746e383ca68d09974947eeca6c17bb132a46a.zip |
After recent OperatingsSystem plug-in changes, the lldb_private::Process and lldb_private::Thread subclasses were changed and the API was not respected properly.
This checkin aims to fix this. The process now has two thread lists: a real thread list for threads that are created by the lldb_private::Process subclass, and the user visible threads. The user visible threads are the same as the real threas when no OS plug-in in used. But when an OS plug-in is used, the user thread can be a combination of real and "memory" threads. Real threads can be placed inside of memory threads so that a thread appears to be different, but is still controlled by the actual real thread. When the thread list needs updating, the lldb_private::Process class will call the: lldb_private::Process::UpdateThreadList() function with the old real thread list, and the function is expected to fill in the new real thread list with the current state of the process. After this function, the process will check if there is an OS plug-in being used, and if so, it will give the old user thread list, the new real thread list and the OS plug-in will create the new user thread list from both of these lists. If there is no OS plug-in, the real thread list is the user thread list.
These changes keep the lldb_private::Process subclasses clean and no changes are required.
llvm-svn: 181091
-rw-r--r-- | lldb/include/lldb/Target/OperatingSystem.h | 4 | ||||
-rw-r--r-- | lldb/include/lldb/Target/Process.h | 5 | ||||
-rw-r--r-- | lldb/include/lldb/Target/ThreadList.h | 7 | ||||
-rw-r--r-- | lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp | 6 | ||||
-rw-r--r-- | lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h | 3 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp | 27 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h | 10 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp | 51 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp | 57 | ||||
-rw-r--r-- | lldb/source/Target/Process.cpp | 24 | ||||
-rw-r--r-- | lldb/source/Target/Thread.cpp | 18 | ||||
-rw-r--r-- | lldb/source/Target/ThreadList.cpp | 62 |
12 files changed, 151 insertions, 123 deletions
diff --git a/lldb/include/lldb/Target/OperatingSystem.h b/lldb/include/lldb/Target/OperatingSystem.h index 3455333ec64..f1c0eb06026 100644 --- a/lldb/include/lldb/Target/OperatingSystem.h +++ b/lldb/include/lldb/Target/OperatingSystem.h @@ -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; diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index 6b84972603e..224efe3782c 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -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; diff --git a/lldb/include/lldb/Target/ThreadList.h b/lldb/include/lldb/Target/ThreadList.h index c219434d152..f1d699d8ffb 100644 --- a/lldb/include/lldb/Target/ThreadList.h +++ b/lldb/include/lldb/Target/ThreadList.h @@ -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: diff --git a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp index fc05d6e18ec..0528033f3b1 100644 --- a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp +++ b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp @@ -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) diff --git a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h index 756d054cca1..0055058192c 100644 --- a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h +++ b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h @@ -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 diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp index f9b1055644b..1ed1cb0aab3 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp @@ -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"); @@ -374,7 +377,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(); @@ -446,15 +450,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; } @@ -471,7 +477,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)); + if (!thread_sp) + thread_sp = GetKernelThread (); + new_thread_list.AddThread(thread_sp); return new_thread_list.GetSize(false) > 0; } @@ -795,7 +804,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()); diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h index 9de262322ae..1dff43f1090 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h @@ -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 diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 06e15ab1f40..0302f9312b7 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -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(); } diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp index 321fe8d819a..40b367c3993 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp @@ -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; - - // 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); + { + 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(); + + 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; diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 227d4c1296c..fda71060d47 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -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); } } } diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index a7e03a2a60d..5096a91cf1f 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -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; + } } } diff --git a/lldb/source/Target/ThreadList.cpp b/lldb/source/Target/ThreadList.cpp index d59d8059b36..80df5957c3f 100644 --- a/lldb/source/Target/ThreadList.cpp +++ b/lldb/source/Target/ThreadList.cpp @@ -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; +} + |