diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index 0e0838d4bc3b..075a3fe46281 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -3250,7 +3250,7 @@ protected: SetPrivateState (lldb::StateType state); bool - StartPrivateStateThread (bool force = false); + StartPrivateStateThread (bool is_secondary_thread = false); void StopPrivateStateThread (); @@ -3261,11 +3261,22 @@ protected: void ResumePrivateStateThread (); + struct PrivateStateThreadArgs + { + Process *process; + bool is_secondary_thread; + }; + static lldb::thread_result_t PrivateStateThread (void *arg); + // The starts up the private state thread that will watch for events from the debugee. + // Pass true for is_secondary_thread in the case where you have to temporarily spin up a + // secondary state thread to handle events from a hand-called function on the primary + // private state thread. + lldb::thread_result_t - RunPrivateStateThread (); + RunPrivateStateThread (bool is_secondary_thread); void HandlePrivateEvent (lldb::EventSP &event_sp); diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index e60fe22cf9d1..77e9b5dbc0ab 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -4271,7 +4271,7 @@ Process::ShouldBroadcastEvent (Event *event_ptr) bool -Process::StartPrivateStateThread (bool force) +Process::StartPrivateStateThread (bool is_secondary_thread) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS)); @@ -4279,7 +4279,7 @@ Process::StartPrivateStateThread (bool force) if (log) log->Printf ("Process::%s()%s ", __FUNCTION__, already_running ? " already running" : " starting private state thread"); - if (!force && already_running) + if (!is_secondary_thread && already_running) return true; // Create a thread that watches our internal state and controls which @@ -4303,7 +4303,8 @@ Process::StartPrivateStateThread (bool force) } // Create the private state thread, and start it running. - m_private_state_thread = ThreadLauncher::LaunchThread(thread_name, Process::PrivateStateThread, this, NULL); + PrivateStateThreadArgs args = {this, is_secondary_thread}; + m_private_state_thread = ThreadLauncher::LaunchThread(thread_name, Process::PrivateStateThread, (void *) &args, NULL); if (m_private_state_thread.IsJoinable()) { ResumePrivateStateThread(); @@ -4533,13 +4534,13 @@ Process::HandlePrivateEvent (EventSP &event_sp) thread_result_t Process::PrivateStateThread (void *arg) { - Process *proc = static_cast (arg); - thread_result_t result = proc->RunPrivateStateThread(); + PrivateStateThreadArgs *real_args = static_cast (arg); + thread_result_t result = real_args->process->RunPrivateStateThread(real_args->is_secondary_thread); return result; } thread_result_t -Process::RunPrivateStateThread () +Process::RunPrivateStateThread (bool is_secondary_thread) { bool control_only = true; m_private_state_control_wait.SetValue (false, eBroadcastNever); @@ -4631,7 +4632,11 @@ Process::RunPrivateStateThread () log->Printf ("Process::%s (arg = %p, pid = %" PRIu64 ") thread exiting...", __FUNCTION__, static_cast(this), GetID()); - m_public_run_lock.SetStopped(); + // If we are a secondary thread, then the primary thread we are working for will have already + // acquired the public_run_lock, and isn't done with what it was doing yet, so don't + // try to change it on the way out. + if (!is_secondary_thread) + m_public_run_lock.SetStopped(); m_private_state_control_wait.SetValue (true, eBroadcastAlways); m_private_state_thread.Reset(); return NULL;