diff options
Diffstat (limited to 'lldb')
| -rw-r--r-- | lldb/include/lldb/Target/Process.h | 12 | ||||
| -rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp | 91 | ||||
| -rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h | 13 | ||||
| -rw-r--r-- | lldb/source/Target/ThreadList.cpp | 18 |
4 files changed, 133 insertions, 1 deletions
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index 0ad33260bb6..772eefb0ac1 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -1753,6 +1753,18 @@ public: m_dynamic_checkers_ap.reset(dynamic_checkers); } + virtual bool + StartNoticingNewThreads() + { + return true; + } + + virtual bool + StopNoticingNewThreads() + { + return true; + } + //------------------------------------------------------------------ // lldb::ExecutionContextScope pure virtual functions //------------------------------------------------------------------ diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 26aa4564281..f0087ec4200 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -119,7 +119,8 @@ ProcessGDBRemote::ProcessGDBRemote(Target& target, Listener &listener) : m_packet_timeout (1), m_max_memory_size (512), m_waiting_for_attach (false), - m_local_debugserver (true) + m_local_debugserver (true), + m_thread_observation_bps() { } @@ -2279,3 +2280,91 @@ ProcessGDBRemote::ListProcessesMatchingName (const char *name, StringList &match } } + +bool +ProcessGDBRemote::NewThreadNotifyBreakpointHit (void *baton, + lldb_private::StoppointCallbackContext *context, + lldb::user_id_t break_id, + lldb::user_id_t break_loc_id) +{ + // I don't think I have to do anything here, just make sure I notice the new thread when it starts to + // run so I can stop it if that's what I want to do. + LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); + if (log) + log->Printf("Hit New Thread Notification breakpoint."); + return false; +} + + +bool +ProcessGDBRemote::StartNoticingNewThreads() +{ + static const char *bp_names[] = + { + "start_wqthread", + "_pthread_start", + NULL + }; + + LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); + size_t num_bps = m_thread_observation_bps.size(); + if (num_bps != 0) + { + for (int i = 0; i < num_bps; i++) + { + lldb::BreakpointSP break_sp = m_target.GetBreakpointByID(m_thread_observation_bps[i]); + if (break_sp) + { + if (log) + log->Printf("Enabled noticing new thread breakpoint."); + break_sp->SetEnabled(true); + } + } + } + else + { + for (int i = 0; bp_names[i] != NULL; i++) + { + Breakpoint *breakpoint = m_target.CreateBreakpoint (NULL, bp_names[i], eFunctionNameTypeFull, true).get(); + if (breakpoint) + { + if (log) + log->Printf("Successfully created new thread notification breakpoint at \"%s\".", bp_names[i]); + m_thread_observation_bps.push_back(breakpoint->GetID()); + breakpoint->SetCallback (ProcessGDBRemote::NewThreadNotifyBreakpointHit, this, true); + } + else + { + if (log) + log->Printf("Failed to create new thread notification breakpoint."); + return false; + } + } + } + + return true; +} + +bool +ProcessGDBRemote::StopNoticingNewThreads() +{ + size_t num_bps = m_thread_observation_bps.size(); + if (num_bps != 0) + { + for (int i = 0; i < num_bps; i++) + { + LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); + + lldb::BreakpointSP break_sp = m_target.GetBreakpointByID(m_thread_observation_bps[i]); + if (break_sp) + { + if (log) + log->Printf ("Disabling new thread notification breakpoint."); + break_sp->SetEnabled(false); + } + } + } + return true; +} + + diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 74905d0e646..ebb4cca23d4 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -216,6 +216,12 @@ public: virtual lldb_private::DynamicLoader * GetDynamicLoader (); + + virtual bool + StartNoticingNewThreads(); + + virtual bool + StopNoticingNewThreads(); protected: friend class ThreadGDBRemote; @@ -336,6 +342,7 @@ protected: size_t m_max_memory_size; // The maximum number of bytes to read/write when reading and writing memory bool m_waiting_for_attach; bool m_local_debugserver; // Is the debugserver process we are talking to local or on another machine. + std::vector<lldb::user_id_t> m_thread_observation_bps; void ResetGDBRemoteState (); @@ -379,6 +386,12 @@ private: //------------------------------------------------------------------ // For ProcessGDBRemote only //------------------------------------------------------------------ + static bool + NewThreadNotifyBreakpointHit (void *baton, + lldb_private::StoppointCallbackContext *context, + lldb::user_id_t break_id, + lldb::user_id_t break_loc_id); + DISALLOW_COPY_AND_ASSIGN (ProcessGDBRemote); }; diff --git a/lldb/source/Target/ThreadList.cpp b/lldb/source/Target/ThreadList.cpp index e5056326b1c..fa1758b54da 100644 --- a/lldb/source/Target/ThreadList.cpp +++ b/lldb/source/Target/ThreadList.cpp @@ -352,6 +352,10 @@ ThreadList::RefreshStateAfterStop () Mutex::Locker locker(m_threads_mutex); m_process->UpdateThreadListIfNeeded(); + + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); + if (log) + log->Printf ("Turning off notification of new threads while single stepping a thread."); collection::iterator pos, end = m_threads.end(); for (pos = m_threads.begin(); pos != end; ++pos) @@ -403,6 +407,20 @@ ThreadList::WillResume () } } + if (wants_solo_run) + { + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); + if (log) + log->Printf ("Turning on notification of new threads while single stepping a thread."); + m_process->StartNoticingNewThreads(); + } + else + { + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); + if (log) + log->Printf ("Turning off notification of new threads while single stepping a thread."); + m_process->StopNoticingNewThreads(); + } // Give all the threads that are likely to run a last chance to set up their state before we // negotiate who is actually going to get a chance to run... |

