diff options
Diffstat (limited to 'lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp')
-rw-r--r-- | lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp | 69 |
1 files changed, 50 insertions, 19 deletions
diff --git a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp index 6f25585ad3f..e09bfcaf418 100644 --- a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp +++ b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp @@ -76,7 +76,8 @@ ProcessPOSIX::ProcessPOSIX(Target& target, Listener &listener) m_monitor(NULL), m_module(NULL), m_message_mutex (Mutex::eMutexTypeRecursive), - m_exit_now(false) + m_exit_now(false), + m_seen_initial_stop() { // FIXME: Putting this code in the ctor and saving the byte order in a // member variable is a hack to avoid const qual issues in GetByteOrder. @@ -412,13 +413,10 @@ ProcessPOSIX::SendMessage(const ProcessMessage &message) m_exit_status = message.GetExitStatus(); SetExitStatus(m_exit_status, NULL); } + else if (!IsAThreadRunning()) + SetPrivateState(eStateStopped); break; - case ProcessMessage::eBreakpointMessage: - case ProcessMessage::eTraceMessage: - case ProcessMessage::eWatchpointMessage: - case ProcessMessage::eNewThreadMessage: - case ProcessMessage::eCrashMessage: assert(thread); thread->SetState(eStateStopped); StopAllThreads(message.GetTID()); @@ -427,21 +425,21 @@ ProcessPOSIX::SendMessage(const ProcessMessage &message) case ProcessMessage::eSignalMessage: case ProcessMessage::eSignalDeliveredMessage: - { - lldb::tid_t tid = message.GetTID(); - lldb::tid_t pid = GetID(); - if (tid == pid) { - assert(thread); - thread->SetState(eStateStopped); - StopAllThreads(message.GetTID()); - SetPrivateState(eStateStopped); - break; - } else { - // FIXME: Ignore any signals generated by children. + if (message.GetSignal() == SIGSTOP && + AddThreadForInitialStopIfNeeded(message.GetTID())) return; - } - } + // Intentional fall-through + case ProcessMessage::eBreakpointMessage: + case ProcessMessage::eTraceMessage: + case ProcessMessage::eWatchpointMessage: + case ProcessMessage::eNewThreadMessage: + case ProcessMessage::eCrashMessage: + assert(thread); + thread->SetState(eStateStopped); + StopAllThreads(message.GetTID()); + SetPrivateState(eStateStopped); + break; } m_message_queue.push(message); @@ -453,6 +451,19 @@ ProcessPOSIX::StopAllThreads(lldb::tid_t stop_tid) // FIXME: Will this work the same way on FreeBSD and Linux? } +bool +ProcessPOSIX::AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid) +{ + bool added_to_set = false; + ThreadStopSet::iterator it = m_seen_initial_stop.find(stop_tid); + if (it == m_seen_initial_stop.end()) + { + m_seen_initial_stop.insert(stop_tid); + added_to_set = true; + } + return added_to_set; +} + void ProcessPOSIX::RefreshStateAfterStop() { @@ -497,6 +508,7 @@ ProcessPOSIX::RefreshStateAfterStop() log->Printf ("ProcessPOSIX::%s() removing thread, tid = %" PRIi64, __FUNCTION__, tid); ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false); thread_sp.reset(); + m_seen_initial_stop.erase(tid); } m_message_queue.pop(); @@ -851,3 +863,22 @@ ProcessPOSIX::IsStopped() return false; } + +bool +ProcessPOSIX::IsAThreadRunning() +{ + bool is_running = false; + uint32_t thread_count = m_thread_list.GetSize(false); + for (uint32_t i = 0; i < thread_count; ++i) + { + POSIXThread *thread = static_cast<POSIXThread*>( + m_thread_list.GetThreadAtIndex(i, false).get()); + StateType thread_state = thread->GetState(); + if (thread_state == eStateRunning || thread_state == eStateStepping) + { + is_running = true; + break; + } + } + return is_running; +} |