Index: source/Plugins/Process/Linux/NativeProcessLinux.h =================================================================== --- source/Plugins/Process/Linux/NativeProcessLinux.h +++ source/Plugins/Process/Linux/NativeProcessLinux.h @@ -356,20 +356,9 @@ // Typedefs. typedef std::unordered_set ThreadIDSet; - // Notify that a thread is created and/or starting to be tracked. - void - NotifyThreadCreate(lldb::tid_t tid); - - - // Notify the delegate after a given set of threads stops. The triggering_tid will be set - // as the current thread. The error_function will be fired if either the triggering tid - // or any of the wait_for_stop_tids are unknown. - void - StopThreads(lldb::tid_t triggering_tid, const ThreadIDSet &wait_for_stop_tids); - - // Notify the delegate after all non-stopped threads stop. The triggering_tid will be set - // as the current thread. The error_function will be fired if the triggering tid - // is unknown. + // This method is requests a stop on all threads which are still running. It sets up a + // deferred delegate notification, which will fire once threads report as stopped. The + // triggerring_tid will be set as the current thread (main stop reason). void StopRunningThreads(lldb::tid_t triggering_tid); @@ -380,30 +369,6 @@ void StopRunningThreadsWithSkipTID(lldb::tid_t triggering_tid, lldb::tid_t skip_stop_request_tid); - // Notify the thread stopped. Will trigger error at time of execution if we - // already think it is stopped. - Error - NotifyThreadStop(lldb::tid_t tid, bool initiated_by_llgs); - - // Request that the given thread id should have the request_thread_resume_function - // called. This call signals an error if the thread resume is for - // a thread that is already in a running state. - Error - RequestThreadResume (lldb::tid_t tid, - const NativeThreadLinux::ResumeThreadFunction &request_thread_resume_function); - - // Request that the given thread id should have the request_thread_resume_function - // called. This call ignores threads that are already running and - // does not trigger an error in that case. - Error - RequestThreadResumeAsNeeded (lldb::tid_t tid, - const NativeThreadLinux::ResumeThreadFunction &request_thread_resume_function); - - // Indicate the calling process did an exec and that the thread state - // should be 100% cleared. - void - ResetForExec (); - private: struct PendingNotification { @@ -444,13 +409,14 @@ void RequestStopOnAllRunningThreads(); - std::mutex m_event_mutex; // Serializes execution of ProcessEvent. XXX - Error ThreadDidStop(lldb::tid_t tid, bool initiated_by_llgs); + // Resume the thread with the given thread id using the request_thread_resume_function + // called. If error_when_already_running is then then an error is raised if we think this + // thread is already running. Error - DoResume(lldb::tid_t tid, NativeThreadLinux::ResumeThreadFunction request_thread_resume_function, + ResumeThread(lldb::tid_t tid, NativeThreadLinux::ResumeThreadFunction request_thread_resume_function, bool error_when_already_running); void @@ -459,9 +425,6 @@ void ThreadWasCreated (lldb::tid_t tid); - void - ThreadDidDie (lldb::tid_t tid); - // Member variables. PendingNotificationUP m_pending_notification_up; }; Index: source/Plugins/Process/Linux/NativeProcessLinux.cpp =================================================================== --- source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -1972,7 +1972,7 @@ thread_sp = AddThread (pid); assert (thread_sp && "AddThread() returned a nullptr thread"); std::static_pointer_cast (thread_sp)->SetStoppedBySignal (SIGSTOP); - NotifyThreadCreate(pid); + ThreadWasCreated(pid); // Let our process instance know the thread has stopped. SetCurrentThreadID (thread_sp->GetID ()); @@ -2068,7 +2068,7 @@ // This will notify this is a new thread and tell the system it is stopped. std::static_pointer_cast (thread_sp)->SetStoppedBySignal (SIGSTOP); - NotifyThreadCreate(tid); + ThreadWasCreated(tid); SetCurrentThreadID (thread_sp->GetID ()); } @@ -2167,9 +2167,6 @@ // This is a thread that exited. Ensure we're not tracking it anymore. const bool thread_found = StopTrackingThread (pid); - // Make sure the thread state coordinator knows about this. - NotifyThreadDeath (pid); - if (is_main_thread) { // We only set the exit status and notify the delegate if we haven't already set the process @@ -2221,7 +2218,8 @@ // This is a group stop reception for this tid. if (log) log->Printf ("NativeThreadLinux::%s received a group stop for pid %" PRIu64 " tid %" PRIu64, __FUNCTION__, GetID (), pid); - NotifyThreadStop (pid, false); + Mutex::Locker locker(m_threads_mutex); + ThreadDidStop(pid, false); } else { @@ -2234,9 +2232,6 @@ // Stop tracking the metadata for the thread since it's entirely off the system now. const bool thread_found = StopTrackingThread (pid); - // Make sure the thread state coordinator knows about this. - NotifyThreadDeath (pid); - if (log) log->Printf ("NativeProcessLinux::%s GetSignalInfo failed: %s, tid = %" PRIu64 ", signal = %d, status = %d (%s, %s, %s)", __FUNCTION__, err.AsCString(), pid, signal, status, err.GetError() == ESRCH ? "thread/process killed" : "unknown reason", is_main_thread ? "is main thread" : "is not main thread", thread_found ? "thread metadata removed" : "thread metadata not found"); @@ -2324,7 +2319,7 @@ new_thread_sp = AddThread(tid); std::static_pointer_cast (new_thread_sp)->SetRunning (); Resume (tid, LLDB_INVALID_SIGNAL_NUMBER); - NotifyThreadCreate(tid); + ThreadWasCreated(tid); } void @@ -2379,8 +2374,8 @@ if (log) log->Printf ("NativeProcessLinux::%s() received exec event, code = %d", __FUNCTION__, info->si_code ^ SIGTRAP); - // The thread state coordinator needs to reset due to the exec. - ResetForExec (); + // Exec clears any pending notifications. + m_pending_notification_up.reset (); // Remove all but the main thread here. Linux fork creates a new process which only copies the main thread. Mutexes are in undefined state. if (log) @@ -2420,7 +2415,7 @@ // Tell coordinator about about the "new" (since exec) stopped main thread. const lldb::tid_t main_thread_tid = GetID (); - NotifyThreadCreate(main_thread_tid); + ThreadWasCreated(main_thread_tid); // NOTE: ideally these next statements would execute at the same time as the coordinator thread create was executed. // Consider a handler that can execute when that happens. @@ -2443,7 +2438,7 @@ break; // This thread is currently stopped. It's not actually dead yet, just about to be. - NotifyThreadStop (pid, false); + ThreadDidStop (pid, false); // The actual stop reason does not matter much, as we are going to resume the thread a // few lines down. If we ever want to report this state to the debugger, then we should // invent a new stop reason. @@ -2468,12 +2463,13 @@ } const int signo = static_cast (data); - RequestThreadResume (pid, + ResumeThread(pid, [=](lldb::tid_t tid_to_resume, bool supress_signal) { std::static_pointer_cast (thread_sp)->SetRunning (); return Resume (tid_to_resume, (supress_signal) ? LLDB_INVALID_SIGNAL_NUMBER : signo); - }); + }, + true); break; } @@ -2512,18 +2508,19 @@ log->Printf ("NativeProcessLinux::%s() received unknown SIGTRAP system call stop event, pid %" PRIu64 "tid %" PRIu64 ", resuming", __FUNCTION__, GetID (), pid); // This thread is currently stopped. - NotifyThreadStop (pid, false); + ThreadDidStop (pid, false); if (thread_sp) std::static_pointer_cast (thread_sp)->SetStoppedBySignal (SIGTRAP); // Ignore these signals until we know more about them. - RequestThreadResume (pid, + ResumeThread(pid, [=](lldb::tid_t tid_to_resume, bool supress_signal) { std::static_pointer_cast (thread_sp)->SetRunning (); return Resume (tid_to_resume, LLDB_INVALID_SIGNAL_NUMBER); - }); + }, + true); break; default: @@ -2547,7 +2544,7 @@ std::static_pointer_cast(thread_sp)->SetStoppedByTrace(); // This thread is currently stopped. - NotifyThreadStop(pid, false); + ThreadDidStop(pid, false); // Here we don't have to request the rest of the threads to stop or request a deferred stop. // This would have already happened at the time the Resume() with step operation was signaled. @@ -2567,7 +2564,7 @@ __FUNCTION__, pid); // This thread is currently stopped. - NotifyThreadStop(pid, false); + ThreadDidStop(pid, false); // Mark the thread as stopped at breakpoint. if (thread_sp) @@ -2613,7 +2610,7 @@ __FUNCTION__, pid, wp_index); // This thread is currently stopped. - NotifyThreadStop(pid, false); + ThreadDidStop(pid, false); // Mark the thread as stopped at watchpoint. // The address is at (lldb::addr_t)info->si_addr if we need it. @@ -2685,7 +2682,7 @@ // We can now resume the newly created thread. std::static_pointer_cast (thread_sp)->SetRunning (); Resume (pid, LLDB_INVALID_SIGNAL_NUMBER); - NotifyThreadCreate(pid); + ThreadWasCreated(pid); // Done handling. return; } @@ -2727,7 +2724,7 @@ linux_thread_sp->SetStoppedBySignal(0); SetCurrentThreadID (thread_sp->GetID ()); - NotifyThreadStop (thread_sp->GetID (), true); + ThreadDidStop (thread_sp->GetID (), true); } else { @@ -2748,8 +2745,7 @@ stop_signo, signal_name); } - // Tell the thread state coordinator about the stop. - NotifyThreadStop (thread_sp->GetID (), false); + ThreadDidStop (thread_sp->GetID (), false); } } @@ -2761,7 +2757,7 @@ log->Printf ("NativeProcessLinux::%s() received signal %s", __FUNCTION__, GetUnixSignals ().GetSignalAsCString (signo)); // This thread is stopped. - NotifyThreadStop (pid, false); + ThreadDidStop (pid, false); switch (signo) { @@ -2778,13 +2774,14 @@ // Resume this thread to get the group-stop mechanism to fire off the true group stops. // This thread will get stopped again as part of the group-stop completion. - RequestThreadResume (pid, + ResumeThread(pid, [=](lldb::tid_t tid_to_resume, bool supress_signal) { std::static_pointer_cast (thread_sp)->SetRunning (); // Pass this signal number on to the inferior to handle. return Resume (tid_to_resume, (supress_signal) ? LLDB_INVALID_SIGNAL_NUMBER : signo); - }); + }, + true); } break; case SIGSEGV: @@ -3056,7 +3053,7 @@ { // Run the thread, possibly feeding it the signal. const int signo = action->signal; - RequestThreadResumeAsNeeded (thread_sp->GetID (), + ResumeThread(thread_sp->GetID (), [=](lldb::tid_t tid_to_resume, bool supress_signal) { std::static_pointer_cast (thread_sp)->SetRunning (); @@ -3065,7 +3062,8 @@ if (resume_result.Success()) SetState(eStateRunning, true); return resume_result; - }); + }, + false); break; } @@ -3073,7 +3071,7 @@ { // Request the step. const int signo = action->signal; - RequestThreadResume (thread_sp->GetID (), + ResumeThread(thread_sp->GetID (), [=](lldb::tid_t tid_to_step, bool supress_signal) { std::static_pointer_cast (thread_sp)->SetStepping (); @@ -3088,7 +3086,8 @@ if (step_result.Success()) SetState(eStateStepping, true); return step_result; - }); + }, + false); stepping = true; break; } @@ -4036,18 +4035,32 @@ bool NativeProcessLinux::StopTrackingThread (lldb::tid_t thread_id) { + Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD); + + if (log) + log->Printf("NativeProcessLinux::%s (tid: %" PRIu64 ")", __FUNCTION__, thread_id); + + bool found = false; + Mutex::Locker locker (m_threads_mutex); for (auto it = m_threads.begin (); it != m_threads.end (); ++it) { if (*it && ((*it)->GetID () == thread_id)) { m_threads.erase (it); - return true; + found = true; + break; } } - // Didn't find it. - return false; + // If we have a pending notification, remove this from the set. + if (m_pending_notification_up) + { + m_pending_notification_up->wait_for_stop_tids.erase(thread_id); + SignalIfRequirementsSatisfied(); + } + + return found; } NativeThreadProtocolSP @@ -4215,12 +4228,16 @@ } Error -NativeProcessLinux::DoResume( +NativeProcessLinux::ResumeThread( lldb::tid_t tid, NativeThreadLinux::ResumeThreadFunction request_thread_resume_function, bool error_when_already_running) { Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD); + + if (log) + log->Printf("NativeProcessLinux::%s (tid: %" PRIu64 ", error_when_already_running: %s)", + __FUNCTION__, tid, error_when_already_running?"true":"false"); auto thread_sp = std::static_pointer_cast(GetThreadByID(tid)); lldbassert(thread_sp != nullptr); @@ -4285,32 +4302,9 @@ //===----------------------------------------------------------------------===// void -NativeProcessLinux::StopThreads(const lldb::tid_t triggering_tid, - const ThreadIDSet &wait_for_stop_tids) -{ - Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD); - std::lock_guard lock(m_event_mutex); - - if (log) - { - log->Printf("NativeProcessLinux::%s about to process event: (triggering_tid: %" PRIu64 ", wait_for_stop_tids.size(): %zd)", - __FUNCTION__, triggering_tid, wait_for_stop_tids.size()); - } - - DoStopThreads(PendingNotificationUP(new PendingNotification( - triggering_tid, wait_for_stop_tids, ThreadIDSet()))); - - if (log) - { - log->Printf("NativeProcessLinux::%s event processing done", __FUNCTION__); - } -} - -void NativeProcessLinux::StopRunningThreads(const lldb::tid_t triggering_tid) { Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD); - std::lock_guard lock(m_event_mutex); if (log) { @@ -4331,7 +4325,6 @@ lldb::tid_t skip_stop_request_tid) { Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD); - std::lock_guard lock(m_event_mutex); if (log) { @@ -4426,6 +4419,12 @@ Error NativeProcessLinux::ThreadDidStop (lldb::tid_t tid, bool initiated_by_llgs) { + Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD); + + if (log) + log->Printf("NativeProcessLinux::%s (tid: %" PRIu64 ", %sinitiated by llgs)", + __FUNCTION__, tid, initiated_by_llgs?"":"not "); + // Ensure we know about the thread. auto thread_sp = std::static_pointer_cast(GetThreadByID(tid)); lldbassert(thread_sp != nullptr); @@ -4445,7 +4444,6 @@ Error error; if (initiated_by_llgs && context.request_resume_function && !stop_was_requested) { - Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD); // We can end up here if stop was initiated by LLGS but by this time a // thread stop has occurred - maybe initiated by another event. if (log) @@ -4489,6 +4487,11 @@ void NativeProcessLinux::ThreadWasCreated (lldb::tid_t tid) { + Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD); + + if (log) + log->Printf("NativeProcessLinux::%s (tid: %" PRIu64 ")", __FUNCTION__, tid); + auto thread_sp = std::static_pointer_cast(GetThreadByID(tid)); lldbassert(thread_sp != nullptr); @@ -4500,138 +4503,3 @@ thread_sp->RequestStop(); } } - -void -NativeProcessLinux::ThreadDidDie (lldb::tid_t tid) -{ - // If we have a pending notification, remove this from the set. - if (m_pending_notification_up) - { - m_pending_notification_up->wait_for_stop_tids.erase(tid); - SignalIfRequirementsSatisfied(); - } -} - -Error -NativeProcessLinux::NotifyThreadStop (lldb::tid_t tid, bool initiated_by_llgs) -{ - Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD); - std::lock_guard lock(m_event_mutex); - - if (log) - { - log->Printf("NativeProcessLinux::%s about to process event: (tid: %" PRIu64 ", %sinitiated by llgs)", - __FUNCTION__, tid, initiated_by_llgs?"":"not "); - } - - Error error = ThreadDidStop (tid, initiated_by_llgs); - - if (log) - { - log->Printf("NativeProcessLinux::%s event processing done", __FUNCTION__); - } - - return error; -} - -Error -NativeProcessLinux::RequestThreadResume (lldb::tid_t tid, - const NativeThreadLinux::ResumeThreadFunction &request_thread_resume_function) -{ - Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD); - std::lock_guard lock(m_event_mutex); - - if (log) - { - log->Printf("NativeProcessLinux::%s about to process event: (tid: %" PRIu64 ")", - __FUNCTION__, tid); - } - - Error error = DoResume(tid, request_thread_resume_function, true); - - if (log) - { - log->Printf("NativeProcessLinux::%s event processing done", __FUNCTION__); - } - - return error; -} - -Error -NativeProcessLinux::RequestThreadResumeAsNeeded (lldb::tid_t tid, - const NativeThreadLinux::ResumeThreadFunction &request_thread_resume_function) -{ - Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD); - std::lock_guard lock(m_event_mutex); - - if (log) - { - log->Printf("NativeProcessLinux::%s about to process event: (tid: %" PRIu64 ")", - __FUNCTION__, tid); - } - - Error error = DoResume (tid, request_thread_resume_function, false); - - if (log) - { - log->Printf("NativeProcessLinux::%s event processing done", __FUNCTION__); - } - - return error; -} - -void -NativeProcessLinux::NotifyThreadCreate(lldb::tid_t tid) -{ - Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD); - std::lock_guard lock(m_event_mutex); - - if (log) - log->Printf("NativeProcessLinux::%s about to process event: (tid: %" PRIu64 ")", __FUNCTION__, tid); - - ThreadWasCreated(tid); - - if (log) - { - log->Printf("NativeProcessLinux::%s event processing done", __FUNCTION__); - } -} - -void -NativeProcessLinux::NotifyThreadDeath (lldb::tid_t tid) -{ - Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD); - std::lock_guard lock(m_event_mutex); - - if (log) - { - log->Printf("NativeProcessLinux::%s about to process event: (tid: %" PRIu64 ")", __FUNCTION__, tid); - } - - ThreadDidDie(tid); - - if (log) - { - log->Printf("NativeProcessLinux::%s event processing done", __FUNCTION__); - } -} - -void -NativeProcessLinux::ResetForExec () -{ - Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD); - std::lock_guard lock(m_event_mutex); - - if (log) - { - log->Printf("NativeProcessLinux::%s about to process event", __FUNCTION__); - } - - // Clear the pending notification if there was one. - m_pending_notification_up.reset (); - - if (log) - { - log->Printf("NativeProcessLinux::%s event processing done", __FUNCTION__); - } -}