diff options
Diffstat (limited to 'lldb/source/Plugins/Process/POSIX')
-rw-r--r-- | lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp | 69 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h | 14 |
2 files changed, 64 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; +} diff --git a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h index 8402aad3496..a865fe26746 100644 --- a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h +++ b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h @@ -14,6 +14,7 @@ // C++ Includes #include <queue> +#include <set> // Other libraries and framework includes #include "lldb/Target/Process.h" @@ -157,6 +158,11 @@ public: virtual void StopAllThreads(lldb::tid_t stop_tid); + /// Adds the thread to the list of threads for which we have received the initial stopping signal. + /// The \p stop_tid paramter indicates the thread which the stop happened for. + bool + AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid); + protected: /// Target byte order. lldb::ByteOrder m_byte_order; @@ -183,8 +189,16 @@ protected: /// Returns true if the process is stopped. bool IsStopped(); + /// Returns true if at least one running is currently running + bool IsAThreadRunning(); + typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap; MMapMap m_addr_to_mmap_size; + + typedef std::set<lldb::tid_t> ThreadStopSet; + /// Every thread begins with a stop signal. This keeps track + /// of the threads for which we have received the stop signal. + ThreadStopSet m_seen_initial_stop; }; #endif // liblldb_MacOSXProcess_H_ |