diff options
Diffstat (limited to 'lldb/source')
| -rw-r--r-- | lldb/source/Plugins/Process/Utility/ThreadMemory.cpp | 6 | ||||
| -rw-r--r-- | lldb/source/Plugins/Process/Utility/ThreadMemory.h | 6 | ||||
| -rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp | 108 | ||||
| -rw-r--r-- | lldb/source/Target/Thread.cpp | 33 |
4 files changed, 98 insertions, 55 deletions
diff --git a/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp b/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp index e7602b89020..62c6aeb9c75 100644 --- a/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp +++ b/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp @@ -57,10 +57,10 @@ bool ThreadMemory::WillResume (StateType resume_state) { ClearStackFrames(); - // Call the Thread::WillResume first. If we stop at a signal, the stop info - // class for signal will set the resume signal that we need below. The signal - // stuff obeys the Process::UnixSignal defaults. Thread::WillResume(resume_state); + + if (m_backing_thread_sp) + return m_backing_thread_sp->WillResume(resume_state); return true; } diff --git a/lldb/source/Plugins/Process/Utility/ThreadMemory.h b/lldb/source/Plugins/Process/Utility/ThreadMemory.h index 095078676be..51a2486f709 100644 --- a/lldb/source/Plugins/Process/Utility/ThreadMemory.h +++ b/lldb/source/Plugins/Process/Utility/ThreadMemory.h @@ -101,6 +101,12 @@ public: m_backing_thread_sp = thread_sp; return (bool)thread_sp; } + + virtual lldb::ThreadSP + GetBackingThread () const + { + return m_backing_thread_sp; + } protected: //------------------------------------------------------------------ diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 257c43a3b25..3c9a8d76136 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -1045,58 +1045,68 @@ ProcessGDBRemote::DoResume () { listener.StartListeningForEvents (&m_async_broadcaster, ProcessGDBRemote::eBroadcastBitAsyncThreadDidExit); + const size_t num_threads = GetThreadList().GetSize(); + StreamString continue_packet; bool continue_packet_error = false; if (m_gdb_comm.HasAnyVContSupport ()) { - continue_packet.PutCString ("vCont"); - - if (!m_continue_c_tids.empty()) + if (m_continue_c_tids.size() == num_threads) { - if (m_gdb_comm.GetVContSupported ('c')) - { - for (tid_collection::const_iterator t_pos = m_continue_c_tids.begin(), t_end = m_continue_c_tids.end(); t_pos != t_end; ++t_pos) - continue_packet.Printf(";c:%4.4" PRIx64, *t_pos); - } - else - continue_packet_error = true; + // All threads are continuing, just send a "c" packet + continue_packet.PutCString ("c"); } - - if (!continue_packet_error && !m_continue_C_tids.empty()) + else { - if (m_gdb_comm.GetVContSupported ('C')) + continue_packet.PutCString ("vCont"); + + if (!m_continue_c_tids.empty()) { - for (tid_sig_collection::const_iterator s_pos = m_continue_C_tids.begin(), s_end = m_continue_C_tids.end(); s_pos != s_end; ++s_pos) - continue_packet.Printf(";C%2.2x:%4.4" PRIx64, s_pos->second, s_pos->first); + if (m_gdb_comm.GetVContSupported ('c')) + { + for (tid_collection::const_iterator t_pos = m_continue_c_tids.begin(), t_end = m_continue_c_tids.end(); t_pos != t_end; ++t_pos) + continue_packet.Printf(";c:%4.4" PRIx64, *t_pos); + } + else + continue_packet_error = true; + } + + if (!continue_packet_error && !m_continue_C_tids.empty()) + { + if (m_gdb_comm.GetVContSupported ('C')) + { + for (tid_sig_collection::const_iterator s_pos = m_continue_C_tids.begin(), s_end = m_continue_C_tids.end(); s_pos != s_end; ++s_pos) + continue_packet.Printf(";C%2.2x:%4.4" PRIx64, s_pos->second, s_pos->first); + } + else + continue_packet_error = true; } - else - continue_packet_error = true; - } - if (!continue_packet_error && !m_continue_s_tids.empty()) - { - if (m_gdb_comm.GetVContSupported ('s')) + if (!continue_packet_error && !m_continue_s_tids.empty()) { - for (tid_collection::const_iterator t_pos = m_continue_s_tids.begin(), t_end = m_continue_s_tids.end(); t_pos != t_end; ++t_pos) - continue_packet.Printf(";s:%4.4" PRIx64, *t_pos); + if (m_gdb_comm.GetVContSupported ('s')) + { + for (tid_collection::const_iterator t_pos = m_continue_s_tids.begin(), t_end = m_continue_s_tids.end(); t_pos != t_end; ++t_pos) + continue_packet.Printf(";s:%4.4" PRIx64, *t_pos); + } + else + continue_packet_error = true; } - else - continue_packet_error = true; - } - - if (!continue_packet_error && !m_continue_S_tids.empty()) - { - if (m_gdb_comm.GetVContSupported ('S')) + + if (!continue_packet_error && !m_continue_S_tids.empty()) { - for (tid_sig_collection::const_iterator s_pos = m_continue_S_tids.begin(), s_end = m_continue_S_tids.end(); s_pos != s_end; ++s_pos) - continue_packet.Printf(";S%2.2x:%4.4" PRIx64, s_pos->second, s_pos->first); + if (m_gdb_comm.GetVContSupported ('S')) + { + for (tid_sig_collection::const_iterator s_pos = m_continue_S_tids.begin(), s_end = m_continue_S_tids.end(); s_pos != s_end; ++s_pos) + continue_packet.Printf(";S%2.2x:%4.4" PRIx64, s_pos->second, s_pos->first); + } + else + continue_packet_error = true; } - else - continue_packet_error = true; + + if (continue_packet_error) + continue_packet.GetString().clear(); } - - if (continue_packet_error) - continue_packet.GetString().clear(); } else continue_packet_error = true; @@ -1106,7 +1116,6 @@ ProcessGDBRemote::DoResume () // Either no vCont support, or we tried to use part of the vCont // packet that wasn't supported by the remote GDB server. // We need to try and make a simple packet that can do our continue - const size_t num_threads = GetThreadList().GetSize(); const size_t num_continue_c_tids = m_continue_c_tids.size(); const size_t num_continue_C_tids = m_continue_C_tids.size(); const size_t num_continue_s_tids = m_continue_s_tids.size(); @@ -1394,6 +1403,29 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet) thread_sp = m_thread_list.FindThreadByID(tid, false); if (!thread_sp) { + // If there is an operating system plug-in it might hiding the actual API + // thread inside a ThreadMemory... + if (GetOperatingSystem()) + { + bool found_backing_thread = false; + const uint32_t num_threads = m_thread_list.GetSize(); + for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) + { + thread_sp = m_thread_list.GetThreadAtIndex(thread_idx)->GetBackingThread(); + if (thread_sp && thread_sp->GetID() == tid) + { + found_backing_thread = true; + break; + } + } + + if (!found_backing_thread) + thread_sp.reset(); + } + } + + if (!thread_sp) + { // Create the thread if we need to thread_sp.reset (new ThreadGDBRemote (*this, tid)); m_thread_list.AddThread(thread_sp); diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index 378d0266d5a..72c9a2a5b64 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -542,20 +542,24 @@ Thread::WillResume (StateType resume_state) // We distinguish between the plan on the top of the stack and the lower // plans in case a plan needs to do any special business before it runs. + bool need_to_resume = false; ThreadPlan *plan_ptr = GetCurrentPlan(); - bool need_to_resume = plan_ptr->WillResume(resume_state, true); - - while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL) - { - plan_ptr->WillResume (resume_state, false); - } - - // If the WillResume for the plan says we are faking a resume, then it will have set an appropriate stop info. - // In that case, don't reset it here. - - if (need_to_resume && resume_state != eStateSuspended) + if (plan_ptr) { - m_actual_stop_info_sp.reset(); + need_to_resume = plan_ptr->WillResume(resume_state, true); + + while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL) + { + plan_ptr->WillResume (resume_state, false); + } + + // If the WillResume for the plan says we are faking a resume, then it will have set an appropriate stop info. + // In that case, don't reset it here. + + if (need_to_resume && resume_state != eStateSuspended) + { + m_actual_stop_info_sp.reset(); + } } return need_to_resume; @@ -571,6 +575,7 @@ bool Thread::ShouldStop (Event* event_ptr) { ThreadPlan *current_plan = GetCurrentPlan(); + bool should_stop = true; Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); @@ -955,8 +960,8 @@ Thread::GetCurrentPlan () { // There will always be at least the base plan. If somebody is mucking with a // thread with an empty plan stack, we should assert right away. - assert (!m_plan_stack.empty()); - + if (m_plan_stack.empty()) + return NULL; return m_plan_stack.back().get(); } |

