Index: source/Plugins/Process/Linux/NativeProcessLinux.h =================================================================== --- source/Plugins/Process/Linux/NativeProcessLinux.h +++ source/Plugins/Process/Linux/NativeProcessLinux.h @@ -107,6 +107,12 @@ Error SetBreakpoint (lldb::addr_t addr, uint32_t size, bool hardware) override; + Error + SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware) override; + + Error + RemoveWatchpoint (lldb::addr_t addr) override; + void DoStopIDBumped (uint32_t newBumpId) override; @@ -182,7 +188,6 @@ Mutex m_mem_region_cache_mutex; std::unique_ptr m_coordinator_up; - HostThread m_coordinator_thread; // List of thread ids stepping with a breakpoint with the address of // the relevan breakpoint @@ -297,15 +302,6 @@ GetCrashReasonForSIGBUS(const siginfo_t *info); #endif - Error - StartCoordinatorThread (); - - static void* - CoordinatorThread (void *arg); - - void - StopCoordinatorThread (); - /// Stops monitoring the child process thread. void StopMonitor(); Index: source/Plugins/Process/Linux/NativeProcessLinux.cpp =================================================================== --- source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -1070,6 +1070,20 @@ PTRACE(PTRACE_DETACH, m_tid, nullptr, 0, 0, m_error); } + class LambdaOperation : public Operation + { + public: + typedef std::function Lambda; + + explicit LambdaOperation(Lambda &&lambda) : m_lambda(std::move(lambda)) {} + + // We assume the lambda has captured the NativeProcessLinux instance if it needed it. + void Execute(NativeProcessLinux *) override { m_lambda(); } + + private: + Lambda m_lambda; + }; + } // end of anonymous namespace // Simple helper function to ensure flags are enabled on the given file @@ -1105,7 +1119,8 @@ // pipe, and the completion of the operation is signalled over the semaphore. // - thread exit event: this is signaled from the Monitor destructor by closing the write end // of the command pipe. -class NativeProcessLinux::Monitor { +class NativeProcessLinux::Monitor +{ private: // The initial monitor operation (launch or attach). It returns a inferior process id. std::unique_ptr m_initial_operation_up; @@ -1617,8 +1632,7 @@ m_supports_mem_region (eLazyBoolCalculate), m_mem_region_cache (), m_mem_region_cache_mutex (), - m_coordinator_up (new ThreadStateCoordinator (GetThreadLoggerFunction ())), - m_coordinator_thread () + m_coordinator_up (new ThreadStateCoordinator (GetThreadLoggerFunction ())) { } @@ -1652,10 +1666,6 @@ StartMonitorThread ([&] (Error &e) { return Launch(args.get(), e); }, error); if (!error.Success ()) return; - - error = StartCoordinatorThread (); - if (!error.Success ()) - return; } void @@ -1705,10 +1715,6 @@ StartMonitorThread ([=] (Error &e) { return Attach(pid, e); }, error); if (!error.Success ()) return; - - error = StartCoordinatorThread (); - if (!error.Success ()) - return; } void @@ -2967,6 +2973,9 @@ Error NativeProcessLinux::Resume (const ResumeActionList &resume_actions) { + Error error; + LambdaOperation op( [&] { + Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); if (log) log->Printf ("NativeProcessLinux::%s called: pid %" PRIu64, __FUNCTION__, GetID ()); @@ -2992,9 +3001,9 @@ if (action->state == eStateStepping) { - Error error = SetupSoftwareSingleStepping(thread_sp); + error = SetupSoftwareSingleStepping(thread_sp); if (error.Fail()) - return error; + return; } } } @@ -3076,8 +3085,9 @@ break; default: - return Error ("NativeProcessLinux::%s (): unexpected state %s specified for pid %" PRIu64 ", tid %" PRIu64, + error = Error ("NativeProcessLinux::%s (): unexpected state %s specified for pid %" PRIu64 ", tid %" PRIu64, __FUNCTION__, StateAsCString (action->state), GetID (), thread_sp->GetID ()); + return; } } @@ -3101,7 +3111,11 @@ }); } - return Error(); + }); + + m_monitor_up->DoOperation(&op); + + return error; } Error @@ -3150,6 +3164,9 @@ Error NativeProcessLinux::Interrupt () { + Error error; + LambdaOperation op( [&] { + // Pick a running thread (or if none, a not-dead stopped thread) as // the chosen thread that will be the stop-reason thread. Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); @@ -3186,11 +3203,11 @@ if (!running_thread_sp && !stopped_thread_sp) { - Error error("found no running/stepping or live stopped threads as target for interrupt"); + error = Error("found no running/stepping or live stopped threads as target for interrupt"); if (log) log->Printf ("NativeProcessLinux::%s skipping due to error: %s", __FUNCTION__, error.AsCString ()); - return error; + return; } NativeThreadProtocolSP deferred_signal_thread_sp = running_thread_sp ? running_thread_sp : stopped_thread_sp; @@ -3214,7 +3231,11 @@ // Tell the process delegate that the process is in a stopped state. SetState (StateType::eStateStopped, true); }); - return Error(); + }); + + m_monitor_up->DoOperation(&op); + + return error; } Error @@ -3818,6 +3839,30 @@ #endif Error +NativeProcessLinux::SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware) +{ + Error error; + LambdaOperation op([&] { + error = NativeProcessProtocol::SetWatchpoint(addr, size, watch_flags, hardware); + }); + + m_monitor_up->DoOperation(&op); + return error; +} + +Error +NativeProcessLinux::RemoveWatchpoint (lldb::addr_t addr) +{ + Error error; + LambdaOperation op([&] { + error = NativeProcessProtocol::RemoveWatchpoint(addr); + }); + + m_monitor_up->DoOperation(&op); + return error; +} + +Error NativeProcessLinux::ReadMemory (lldb::addr_t addr, void *buf, lldb::addr_t size, lldb::addr_t &bytes_read) { ReadOperation op(addr, buf, size, bytes_read); @@ -3976,74 +4021,9 @@ void NativeProcessLinux::StopMonitor() { - StopCoordinatorThread (); m_monitor_up.reset(); } -Error -NativeProcessLinux::StartCoordinatorThread () -{ - Error error; - static const char *g_thread_name = "lldb.process.linux.ts_coordinator"; - Log *const log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); - - // Skip if thread is already running - if (m_coordinator_thread.IsJoinable()) - { - error.SetErrorString ("ThreadStateCoordinator's run loop is already running"); - if (log) - log->Printf ("NativeProcessLinux::%s %s", __FUNCTION__, error.AsCString ()); - return error; - } - - // Enable verbose logging if lldb thread logging is enabled. - m_coordinator_up->LogEnableEventProcessing (log != nullptr); - - if (log) - log->Printf ("NativeProcessLinux::%s launching ThreadStateCoordinator thread for pid %" PRIu64, __FUNCTION__, GetID ()); - m_coordinator_thread = ThreadLauncher::LaunchThread(g_thread_name, CoordinatorThread, this, &error); - return error; -} - -void * -NativeProcessLinux::CoordinatorThread (void *arg) -{ - Log *const log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); - - NativeProcessLinux *const process = static_cast (arg); - assert (process && "null process passed to CoordinatorThread"); - if (!process) - { - if (log) - log->Printf ("NativeProcessLinux::%s null process, exiting ThreadStateCoordinator processing loop", __FUNCTION__); - return nullptr; - } - - // Run the thread state coordinator loop until it is done. This call uses - // efficient waiting for an event to be ready. - while (process->m_coordinator_up->ProcessNextEvent () == ThreadStateCoordinator::eventLoopResultContinue) - { - } - - if (log) - log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " exiting ThreadStateCoordinator processing loop due to coordinator indicating completion", __FUNCTION__, process->GetID ()); - - return nullptr; -} - -void -NativeProcessLinux::StopCoordinatorThread() -{ - Log *const log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); - if (log) - log->Printf ("NativeProcessLinux::%s requesting ThreadStateCoordinator stop for pid %" PRIu64, __FUNCTION__, GetID ()); - - // Tell the coordinator we're done. This will cause the coordinator - // run loop thread to exit when the processing queue hits this message. - m_coordinator_up->StopCoordinator (); - m_coordinator_thread.Join (nullptr); -} - bool NativeProcessLinux::HasThreadNoLock (lldb::tid_t thread_id) { Index: source/Plugins/Process/Linux/ThreadStateCoordinator.h =================================================================== --- source/Plugins/Process/Linux/ThreadStateCoordinator.h +++ source/Plugins/Process/Linux/ThreadStateCoordinator.h @@ -10,10 +10,8 @@ #ifndef lldb_ThreadStateCoordinator_h #define lldb_ThreadStateCoordinator_h -#include #include #include -#include #include #include @@ -126,24 +124,9 @@ // Indicate the calling process did an exec and that the thread state // should be 100% cleared. - // - // Note this will clear out any pending notifications, but will not stop - // a notification currently in progress via ProcessNextEvent(). void ResetForExec (); - // Indicate when the coordinator should shut down. - void - StopCoordinator (); - - // Process the next event, returning false when the coordinator is all done. - // This call is synchronous and blocks when there are no events pending. - // Expected usage is to run this in a separate thread until the function - // returns false. Always call this from the same thread. The processing - // logic assumes the execution of this is implicitly serialized. - EventLoopResult - ProcessNextEvent (); - // Enable/disable verbose logging of event processing. void LogEnableEventProcessing (bool enabled); @@ -159,13 +142,10 @@ class EventThreadDeath; class EventRequestResume; - class EventStopCoordinator; class EventReset; typedef std::shared_ptr EventBaseSP; - typedef std::queue QueueType; - enum class ThreadState { Running, @@ -181,12 +161,10 @@ typedef std::unordered_map TIDContextMap; - // Private member functions. - void - EnqueueEvent (EventBaseSP event_sp); + std::mutex m_event_mutex; // Serializes execution of ProcessEvent. - EventBaseSP - DequeueEventWithWait (); + void + ProcessEvent (const EventBaseSP &event_sp); void SetPendingNotification (const EventBaseSP &event_sp); @@ -215,14 +193,6 @@ // Member variables. LogFunction m_log_function; - QueueType m_event_queue; - // For now we do simple read/write lock strategy with efficient wait-for-data. - // We can replace with an entirely non-blocking queue later but we still want the - // reader to sleep when nothing is available - this will be a bursty but infrequent - // event mechanism. - std::condition_variable m_queue_condition; - std::mutex m_queue_mutex; - EventBaseSP m_pending_notification_sp; // Maps known TIDs to ThreadContext. Index: source/Plugins/Process/Linux/ThreadStateCoordinator.cpp =================================================================== --- source/Plugins/Process/Linux/ThreadStateCoordinator.cpp +++ source/Plugins/Process/Linux/ThreadStateCoordinator.cpp @@ -46,29 +46,6 @@ //===----------------------------------------------------------------------===// -class ThreadStateCoordinator::EventStopCoordinator : public ThreadStateCoordinator::EventBase -{ -public: - EventStopCoordinator (): - EventBase () - { - } - - EventLoopResult - ProcessEvent(ThreadStateCoordinator &coordinator) override - { - return eventLoopResultStop; - } - - std::string - GetDescription () override - { - return "EventStopCoordinator"; - } -}; - -//===----------------------------------------------------------------------===// - class ThreadStateCoordinator::EventCallAfterThreadsStop : public ThreadStateCoordinator::EventBase { public: @@ -588,42 +565,12 @@ ThreadStateCoordinator::ThreadStateCoordinator (const LogFunction &log_function) : m_log_function (log_function), - m_event_queue (), - m_queue_condition (), - m_queue_mutex (), m_tid_map (), m_log_event_processing (false) { } void -ThreadStateCoordinator::EnqueueEvent (EventBaseSP event_sp) -{ - std::lock_guard lock (m_queue_mutex); - - m_event_queue.push (event_sp); - if (m_log_event_processing) - Log ("ThreadStateCoordinator::%s enqueued event: %s", __FUNCTION__, event_sp->GetDescription ().c_str ()); - - m_queue_condition.notify_one (); -} - -ThreadStateCoordinator::EventBaseSP -ThreadStateCoordinator::DequeueEventWithWait () -{ - // Wait for an event to be present. - std::unique_lock lock (m_queue_mutex); - m_queue_condition.wait (lock, - [this] { return !m_event_queue.empty (); }); - - // Grab the event and pop it off the queue. - EventBaseSP event_sp = m_event_queue.front (); - m_event_queue.pop (); - - return event_sp; -} - -void ThreadStateCoordinator::SetPendingNotification (const EventBaseSP &event_sp) { assert (event_sp && "null event_sp"); @@ -653,11 +600,11 @@ const ThreadIDFunction &call_after_function, const ErrorFunction &error_function) { - EnqueueEvent (EventBaseSP (new EventCallAfterThreadsStop (triggering_tid, - wait_for_stop_tids, - request_thread_stop_function, - call_after_function, - error_function))); + ProcessEvent(EventBaseSP(new EventCallAfterThreadsStop (triggering_tid, + wait_for_stop_tids, + request_thread_stop_function, + call_after_function, + error_function))); } void @@ -666,10 +613,10 @@ const ThreadIDFunction &call_after_function, const ErrorFunction &error_function) { - EnqueueEvent (EventBaseSP (new EventCallAfterThreadsStop (triggering_tid, - request_thread_stop_function, - call_after_function, - error_function))); + ProcessEvent(EventBaseSP(new EventCallAfterThreadsStop (triggering_tid, + request_thread_stop_function, + call_after_function, + error_function))); } void @@ -679,11 +626,11 @@ const ThreadIDFunction &call_after_function, const ErrorFunction &error_function) { - EnqueueEvent (EventBaseSP (new EventCallAfterThreadsStop (triggering_tid, - request_thread_stop_function, - call_after_function, - skip_stop_request_tids, - error_function))); + ProcessEvent(EventBaseSP(new EventCallAfterThreadsStop (triggering_tid, + request_thread_stop_function, + call_after_function, + skip_stop_request_tids, + error_function))); } @@ -826,7 +773,7 @@ bool initiated_by_llgs, const ErrorFunction &error_function) { - EnqueueEvent (EventBaseSP (new EventThreadStopped (tid, initiated_by_llgs, error_function))); + ProcessEvent(EventBaseSP(new EventThreadStopped (tid, initiated_by_llgs, error_function))); } void @@ -834,7 +781,7 @@ const ResumeThreadFunction &request_thread_resume_function, const ErrorFunction &error_function) { - EnqueueEvent (EventBaseSP (new EventRequestResume (tid, request_thread_resume_function, error_function, true))); + ProcessEvent(EventBaseSP(new EventRequestResume (tid, request_thread_resume_function, error_function, true))); } void @@ -842,7 +789,7 @@ const ResumeThreadFunction &request_thread_resume_function, const ErrorFunction &error_function) { - EnqueueEvent (EventBaseSP (new EventRequestResume (tid, request_thread_resume_function, error_function, false))); + ProcessEvent(EventBaseSP(new EventRequestResume (tid, request_thread_resume_function, error_function, false))); } void @@ -850,56 +797,26 @@ bool is_stopped, const ErrorFunction &error_function) { - EnqueueEvent (EventBaseSP (new EventThreadCreate (tid, is_stopped, error_function))); + ProcessEvent(EventBaseSP(new EventThreadCreate (tid, is_stopped, error_function))); } void ThreadStateCoordinator::NotifyThreadDeath (lldb::tid_t tid, const ErrorFunction &error_function) { - EnqueueEvent (EventBaseSP (new EventThreadDeath (tid, error_function))); + ProcessEvent(EventBaseSP(new EventThreadDeath (tid, error_function))); } void ThreadStateCoordinator::ResetForExec () { - std::lock_guard lock (m_queue_mutex); - - // Remove everything from the queue. This is the only - // state mutation that takes place outside the processing - // loop. - QueueType empty_queue; - m_event_queue.swap (empty_queue); - - // Do the real clear behavior on the the queue to eliminate - // the chance that processing of a dequeued earlier event is - // overlapping with the clearing of state here. Push it - // directly because we need to have this happen with the lock, - // and so far I only have this one place that needs a no-lock - // variant. - m_event_queue.push (EventBaseSP (new EventReset ())); + ProcessEvent(EventBaseSP(new EventReset())); } void -ThreadStateCoordinator::StopCoordinator () +ThreadStateCoordinator::ProcessEvent (const EventBaseSP &event_sp) { - EnqueueEvent (EventBaseSP (new EventStopCoordinator ())); -} - -ThreadStateCoordinator::EventLoopResult -ThreadStateCoordinator::ProcessNextEvent () -{ - // Dequeue the next event, synchronous. - if (m_log_event_processing) - Log ("ThreadStateCoordinator::%s about to dequeue next event in blocking mode", __FUNCTION__); - - EventBaseSP event_sp = DequeueEventWithWait(); - assert (event_sp && "event should never be null"); - if (!event_sp) - { - Log ("ThreadStateCoordinator::%s error: event_sp was null, signaling exit of event loop.", __FUNCTION__); - return eventLoopResultStop; - } + std::lock_guard lock(m_event_mutex); if (m_log_event_processing) { @@ -907,15 +824,12 @@ } // Process the event. - const EventLoopResult result = event_sp->ProcessEvent (*this); + event_sp->ProcessEvent (*this); if (m_log_event_processing) { - Log ("ThreadStateCoordinator::%s event processing returned value %s", __FUNCTION__, - result == eventLoopResultContinue ? "eventLoopResultContinue" : "eventLoopResultStop"); + Log ("ThreadStateCoordinator::%s event processing done", __FUNCTION__); } - - return result; } void Index: unittests/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp =================================================================== --- unittests/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp +++ unittests/Plugins/Process/Linux/ThreadStateCoordinatorTest.cpp @@ -22,12 +22,11 @@ // These are single-line macros so that IDE integration of gtest results puts // the error markers on the correct failure point within the gtest. -#define ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS() ASSERT_EQ (ThreadStateCoordinator::eventLoopResultContinue, m_coordinator.ProcessNextEvent ()); \ +#define ASSERT_PROCESS_EVENT_SUCCEEDED() do { \ if (HasError ()) { printf ("unexpected error in processing of event, error: %s\n", m_error_string.c_str ()); } \ -ASSERT_EQ (false, HasError ()); +ASSERT_EQ (false, HasError ()); } while(0) -#define ASSERT_PROCESS_NEXT_EVENT_FAILS() ASSERT_EQ (ThreadStateCoordinator::eventLoopResultContinue, m_coordinator.ProcessNextEvent ()); \ -ASSERT_EQ (true, HasError ()); +#define ASSERT_PROCESS_EVENT_FAILED() ASSERT_EQ (true, HasError ()) class ThreadStateCoordinatorTest: public ::testing::Test { @@ -142,14 +141,14 @@ SetupKnownRunningThread (lldb::tid_t tid) { NotifyThreadCreate (tid, false); - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); } void SetupKnownStoppedThread (lldb::tid_t tid) { NotifyThreadCreate (tid, true); - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); } // Convenience wrappers for ThreadStateCoordinator, using defaults for expected arguments @@ -194,13 +193,6 @@ }; } -TEST_F (ThreadStateCoordinatorTest, StopCoordinatorWorksNoPriorEvents) -{ - m_coordinator.StopCoordinator (); - ASSERT_EQ (ThreadStateCoordinator::eventLoopResultStop, m_coordinator.ProcessNextEvent ()); - ASSERT_EQ (false, HasError ()); -} - TEST_F (ThreadStateCoordinatorTest, NotifyThreadCreateSignalsErrorOnAlreadyKnownThread) { // Let the coordinator know about our thread. @@ -210,7 +202,7 @@ NotifyThreadCreate (TRIGGERING_TID, true); // This should error out. - ASSERT_PROCESS_NEXT_EVENT_FAILS (); + ASSERT_PROCESS_EVENT_FAILED (); } @@ -222,7 +214,7 @@ NotifyThreadDeath (UNKNOWN_TID); // This should error out. - ASSERT_PROCESS_NEXT_EVENT_FAILS (); + ASSERT_PROCESS_EVENT_FAILED (); } TEST_F (ThreadStateCoordinatorTest, NotifyThreadStopSignalsErrorOnUnknownThread) @@ -231,7 +223,7 @@ // Notify an unknown thread has stopped. NotifyThreadStop (UNKNOWN_TID); - ASSERT_PROCESS_NEXT_EVENT_FAILS (); + ASSERT_PROCESS_EVENT_FAILED (); } TEST_F (ThreadStateCoordinatorTest, CallAfterTheadsStopSignalsErrorOnUnknownDeferredThread) @@ -246,7 +238,7 @@ ASSERT_EQ (false, DidFireDeferredNotification ()); // Event should fail because trigger tid is unknown. - ASSERT_PROCESS_NEXT_EVENT_FAILS (); + ASSERT_PROCESS_EVENT_FAILED (); // Shouldn't have fired due to error. ASSERT_EQ (false, DidFireDeferredNotification ()); @@ -268,7 +260,7 @@ ASSERT_EQ (false, DidFireDeferredNotification ()); // Event should fail because trigger tid is unknown. - ASSERT_PROCESS_NEXT_EVENT_FAILS (); + ASSERT_PROCESS_EVENT_FAILED (); // Shouldn't have triggered deferred notification due to error. ASSERT_EQ (false, DidFireDeferredNotification ()); @@ -285,14 +277,9 @@ // Notify we have a trigger that needs to be fired when all threads in the wait tid set have stopped. CallAfterThreadsStop (TRIGGERING_TID, EMPTY_THREAD_ID_SET); + ASSERT_PROCESS_EVENT_SUCCEEDED (); - // Notification trigger shouldn't go off yet. - ASSERT_EQ (false, DidFireDeferredNotification ()); - - // Process next event. This will pick up the call after threads stop event. - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); - - // Now the trigger should have fired, since there were no threads that needed to first stop. + // The trigger should have fired, since there were no threads that needed to first stop. ASSERT_EQ (true, DidFireDeferredNotification ()); ASSERT_EQ (TRIGGERING_TID, GetDeferredNotificationTID ()); } @@ -310,15 +297,9 @@ // Notify we have a trigger that needs to be fired when all threads in the wait tid set have stopped. CallAfterThreadsStop (TRIGGERING_TID, pending_stop_tids); + ASSERT_PROCESS_EVENT_SUCCEEDED (); - // Neither trigger should have gone off yet. - ASSERT_EQ (false, DidFireDeferredNotification ()); - ASSERT_EQ (false, DidRequestStopForTid (PENDING_STOP_TID)); - - // Process next event. - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); - - // Now the request thread stop should have been called for the pending stop. + // The request thread stop should have been called for the pending stop. ASSERT_EQ (true, DidRequestStopForTid (PENDING_STOP_TID)); // But we still shouldn't have the deferred signal call go off yet. Need to wait for the stop to be reported. @@ -326,12 +307,7 @@ // Now report the that the pending stop occurred. NotifyThreadStop (PENDING_STOP_TID); - - // Shouldn't take effect until after next processing step. - ASSERT_EQ (false, DidFireDeferredNotification ()); - - // Process next event. - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); // Deferred signal notification should have fired now. ASSERT_EQ (true, DidFireDeferredNotification ()); @@ -350,15 +326,9 @@ // Notify we have a trigger that needs to be fired when all threads in the wait tid set have stopped. CallAfterThreadsStop (TRIGGERING_TID, pending_stop_tids); + ASSERT_PROCESS_EVENT_SUCCEEDED (); - // Neither trigger should have gone off yet. - ASSERT_EQ (false, DidFireDeferredNotification ()); - ASSERT_EQ (0u, GetRequestedStopCount ()); - - // Process next event. - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); - - // Now the request thread stops should have been called for the pending stop tids. + // The request thread stops should have been called for the pending stop tids. ASSERT_EQ (2u, GetRequestedStopCount ()); ASSERT_EQ (true, DidRequestStopForTid (PENDING_STOP_TID)); ASSERT_EQ (true, DidRequestStopForTid (PENDING_STOP_TID_02)); @@ -368,15 +338,14 @@ // Report the that the first pending stop occurred. NotifyThreadStop (PENDING_STOP_TID); - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); // Shouldn't take effect until after both pending threads are notified. ASSERT_EQ (false, DidFireDeferredNotification ()); // Report the that the first pending stop occurred. NotifyThreadStop (PENDING_STOP_TID_02); - ASSERT_EQ (false, DidFireDeferredNotification ()); - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); // Deferred signal notification should have fired now. ASSERT_EQ (true, DidFireDeferredNotification ()); @@ -393,18 +362,12 @@ // Tell m_coordinator the pending stop tid is already stopped. NotifyThreadStop (PENDING_STOP_TID); - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); // Notify we have a trigger that needs to be fired when all threads in the wait tid set have stopped. CallAfterThreadsStop (TRIGGERING_TID, pending_stop_tids); - - // Neither trigger should have gone off yet. - ASSERT_EQ (false, DidFireDeferredNotification ()); - ASSERT_EQ (false, DidRequestStopForTid (PENDING_STOP_TID)); - - // Process next event. - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); // The pending stop should *not* fire because the m_coordinator knows it has already stopped. ASSERT_EQ (false, DidRequestStopForTid (PENDING_STOP_TID)); @@ -424,18 +387,12 @@ // Tell coordinator the pending stop tid is already stopped. NotifyThreadStop (PENDING_STOP_TID); - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); // Notify we have a trigger that needs to be fired when all threads in the wait tid set have stopped. CallAfterThreadsStop (TRIGGERING_TID, pending_stop_tids); - - // Neither trigger should have gone off yet. - ASSERT_EQ (false, DidFireDeferredNotification ()); - ASSERT_EQ (0u, GetRequestedStopCount ()); - - // Process next event. - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); // The pending stop should only fire for one of the threads, the one that wasn't already stopped. ASSERT_EQ (true, DidRequestStopForTid (PENDING_STOP_TID_02)); @@ -446,7 +403,7 @@ // Notify final thread has stopped. NotifyThreadStop (PENDING_STOP_TID_02); - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); // The deferred signal notification should have fired since all requirements were met. ASSERT_EQ (true, DidFireDeferredNotification ()); @@ -463,15 +420,9 @@ // Notify we have a trigger that needs to be fired when all threads in the wait tid set have stopped. CallAfterThreadsStop (TRIGGERING_TID, pending_stop_tids); + ASSERT_PROCESS_EVENT_SUCCEEDED (); - // Neither trigger should have gone off yet. - ASSERT_EQ (false, DidFireDeferredNotification ()); - ASSERT_EQ (0u, GetRequestedStopCount ()); - - // Process next event. - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); - - // Now the request thread stop should have been called for the pending stop. + // The request thread stop should have been called for the pending stop. ASSERT_EQ (true, DidRequestStopForTid (PENDING_STOP_TID)); // But we still shouldn't have the deferred signal call go off yet. Need to wait for the death to be reported. @@ -479,12 +430,7 @@ // Now report the that the thread with pending stop dies. NotifyThreadDeath (PENDING_STOP_TID); - - // Shouldn't take effect until after next processing step. - ASSERT_EQ (false, DidFireDeferredNotification ()); - - // Process next event. - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); // Deferred signal notification should have fired now. ASSERT_EQ (true, DidFireDeferredNotification ()); @@ -501,13 +447,7 @@ // Notify we have a trigger that needs to be fired when all threads in the wait tid set have stopped. CallAfterThreadsStop (TRIGGERING_TID, pending_stop_tids); - - // Neither trigger should have gone off yet. - ASSERT_EQ (false, DidFireDeferredNotification ()); - ASSERT_EQ (0u, GetRequestedStopCount ()); - - // Process next event. - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); // Now the request thread stop should have been called for the pending stop. ASSERT_EQ (true, DidRequestStopForTid (PENDING_STOP_TID)); @@ -526,39 +466,18 @@ // trigger the pending notification because we should now require the // new thread to stop too. NotifyThreadStop (PENDING_STOP_TID); - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); ASSERT_EQ (false, DidFireDeferredNotification ()); // Now notify the new thread stopped. NotifyThreadStop (NEW_THREAD_TID); - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); // Deferred signal notification should have fired now. ASSERT_EQ (true, DidFireDeferredNotification ()); ASSERT_EQ (TRIGGERING_TID, GetDeferredNotificationTID ()); } -TEST_F (ThreadStateCoordinatorTest, DeferredNotificationRemovedByResetForExec) -{ - SetupKnownStoppedThread (TRIGGERING_TID); - - // Notify we have a trigger that needs to be fired when all threads in the wait tid set have stopped. - CallAfterThreadsStop (TRIGGERING_TID, - EMPTY_THREAD_ID_SET); - - // Notification trigger shouldn't go off yet. - ASSERT_EQ (false, DidFireDeferredNotification ()); - - // Now indicate an exec occurred, which will invalidate all state about the process and threads. - m_coordinator.ResetForExec (); - - // Verify the deferred stop notification does *not* fire with the next - // process. It will handle the reset and not the deferred signaling, which - // should now be removed. - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); - ASSERT_EQ (false, DidFireDeferredNotification ()); -} - TEST_F (ThreadStateCoordinatorTest, RequestThreadResumeSignalsErrorOnUnknownThread) { const lldb::tid_t UNKNOWN_TID = 411; @@ -574,7 +493,7 @@ ASSERT_EQ (0, resume_call_count); // Process next event. This should fail since the coordinator doesn't know about the thread. - ASSERT_PROCESS_NEXT_EVENT_FAILS (); + ASSERT_PROCESS_EVENT_FAILED (); ASSERT_EQ (0, resume_call_count); } @@ -590,11 +509,7 @@ m_coordinator.RequestThreadResume (NEW_THREAD_TID, GetResumeThreadFunction(resumed_tid, resume_call_count), GetErrorFunction ()); - // Shouldn't be called yet. - ASSERT_EQ (0, resume_call_count); - - // Process next event. After that, the resume request call should have fired. - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); ASSERT_EQ (1, resume_call_count); ASSERT_EQ (NEW_THREAD_TID, resumed_tid); } @@ -611,11 +526,7 @@ m_coordinator.RequestThreadResume (NEW_THREAD_TID, GetResumeThreadFunction(resumed_tid, resume_call_count), GetErrorFunction ()); - // Shouldn't be called yet. - ASSERT_EQ (0, resume_call_count); - - // Process next event. After that, the resume request call should have fired. - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); ASSERT_EQ (1, resume_call_count); ASSERT_EQ (NEW_THREAD_TID, resumed_tid); @@ -625,8 +536,8 @@ GetResumeThreadFunction(resumed_tid, resume_call_count), GetErrorFunction ()); - // Process next event. This should fail since the thread should already be running. - ASSERT_PROCESS_NEXT_EVENT_FAILS (); + // This should fail since the thread should already be running. + ASSERT_PROCESS_EVENT_FAILED (); // And the resume count should not have increased. ASSERT_EQ (initial_resume_call_count, resume_call_count); @@ -649,7 +560,7 @@ ASSERT_EQ (0, resume_call_count); // Process next event. Should be an error. - ASSERT_PROCESS_NEXT_EVENT_FAILS (); + ASSERT_PROCESS_EVENT_FAILED (); // The resume request should not have gone off because we think it is already running. ASSERT_EQ (0, resume_call_count); @@ -680,13 +591,7 @@ // Notify we have a trigger that needs to be fired when all threads in the wait tid set have stopped. CallAfterThreadsStop (TRIGGERING_TID, pending_stop_tids); - - // Neither trigger should have gone off yet. - ASSERT_EQ (false, DidFireDeferredNotification ()); - ASSERT_EQ (0u, GetRequestedStopCount ()); - - // Execute CallAfterThreadsStop. - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); // Both TID A and TID B should have had stop requests made. ASSERT_EQ (2u, GetRequestedStopCount ()); @@ -698,7 +603,7 @@ // Report thread A stopped. NotifyThreadStop (PENDING_TID_A); - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); ASSERT_EQ (false, DidFireDeferredNotification ()); // Now report thread A is resuming. Ensure the resume is called. @@ -707,15 +612,13 @@ m_coordinator.RequestThreadResume (PENDING_TID_A, GetResumeThreadFunction(resumed_tid, resume_call_count), GetErrorFunction ()); - ASSERT_EQ (0, resume_call_count); - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); ASSERT_EQ (1, resume_call_count); ASSERT_EQ (PENDING_TID_A, resumed_tid); // Report thread B stopped. NotifyThreadStop (PENDING_TID_B); - ASSERT_EQ (false, DidFireDeferredNotification ()); - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); // After notifying thread b stopped, we now have thread a resumed but thread b stopped. // However, since thread a had stopped, we now have had both requirements stopped at some point. @@ -731,14 +634,9 @@ // Notify we have a trigger that needs to be fired when all running threads have stopped. CallAfterRunningThreadsStop (TRIGGERING_TID); + ASSERT_PROCESS_EVENT_SUCCEEDED (); - // Notification trigger shouldn't go off yet. - ASSERT_EQ (false, DidFireDeferredNotification ()); - - // Process next event. This will pick up the call after threads stop event. - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); - - // Now the trigger should have fired, since there were no threads that needed to first stop. + // The trigger should have fired, since there were no threads that needed to first stop. ASSERT_EQ (true, DidFireDeferredNotification ()); ASSERT_EQ (TRIGGERING_TID, GetDeferredNotificationTID ()); @@ -760,7 +658,7 @@ ASSERT_EQ (false, DidFireDeferredNotification ()); // Process next event. This will pick up the call after threads stop event. - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); // We should have two stop requests for the two threads currently running. ASSERT_EQ (2u, GetRequestedStopCount ()); @@ -772,11 +670,11 @@ // Now notify the two threads stopped. NotifyThreadStop (PENDING_STOP_TID); - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); ASSERT_EQ (false, DidFireDeferredNotification ()); NotifyThreadStop (PENDING_STOP_TID_02); - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); // Now the trigger should have fired, since there were no threads that needed to first stop. ASSERT_EQ (true, DidFireDeferredNotification ()); @@ -797,7 +695,7 @@ ASSERT_EQ (false, DidFireDeferredNotification ()); // Process next event. This will pick up the call after threads stop event. - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); // We should have two stop requests for the two threads currently running. ASSERT_EQ (1u, GetRequestedStopCount ()); @@ -808,7 +706,7 @@ // Now notify the two threads stopped. NotifyThreadStop (PENDING_STOP_TID); - ASSERT_PROCESS_NEXT_EVENT_SUCCEEDS (); + ASSERT_PROCESS_EVENT_SUCCEEDED (); // Now the trigger should have fired, since there were no threads that needed to first stop. ASSERT_EQ (true, DidFireDeferredNotification ());