diff options
| author | Chaoren Lin <chaorenl@google.com> | 2015-02-03 01:50:57 +0000 |
|---|---|---|
| committer | Chaoren Lin <chaorenl@google.com> | 2015-02-03 01:50:57 +0000 |
| commit | aab58633b719c23760c39320e4792f96568fef58 (patch) | |
| tree | cab845549f928192cd46cff909b0e161ede15601 /lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp | |
| parent | c0e5ac84b0afad7181b21e2328c7cb973bceffe9 (diff) | |
Added code to prevent "administrative stop" from overwriting a real stop reason.
Note this code path should not happen - it implies a bug in another part of
the code. For the thread to receive the stop signal as it is handled, the
and for it to already have a stop reason, it implies the kernel was able to
tell the thread that it stopped while it was stopped. More likely this
seems to indicate a bug where an actual thread start was not getting correctly
logged. If it does get hit, we'll want to understand the sequence to figure
out if it is truly legitimate or if it implies another bug.
llvm-svn: 227916
Diffstat (limited to 'lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp')
| -rw-r--r-- | lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp index 436f4e23c161..7b3d72c2c744 100644 --- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -2521,11 +2521,44 @@ NativeProcessLinux::MonitorSignal(const siginfo_t *info, lldb::pid_t pid, bool e GetID (), pid); - // An inferior thread just stopped, but was not the primary cause of the process stop. - // Instead, something else (like a breakpoint or step) caused the stop. Mark the - // stop signal as 0 to let lldb know this isn't the important stop. - reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetStoppedBySignal (0); - SetCurrentThreadID (thread_sp->GetID ()); + // Check that we're not already marked with a stop reason. + // Note this thread really shouldn't already be marked as stopped - if we were, that would imply that + // the kernel signaled us with the thread stopping which we handled and marked as stopped, + // and that, without an intervening resume, we received another stop. It is more likely + // that we are missing the marking of a run state somewhere if we find that the thread was + // marked as stopped. + NativeThreadLinux *const linux_thread_p = reinterpret_cast<NativeThreadLinux*> (thread_sp.get ()); + assert (linux_thread_p && "linux_thread_p is null!"); + + const StateType thread_state = linux_thread_p->GetState (); + if (!StateIsStoppedState (thread_state, false)) + { + // An inferior thread just stopped, but was not the primary cause of the process stop. + // Instead, something else (like a breakpoint or step) caused the stop. Mark the + // stop signal as 0 to let lldb know this isn't the important stop. + reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetStoppedBySignal (0); + SetCurrentThreadID (thread_sp->GetID ()); + } + else + { + if (log) + { + // Retrieve the signal name if the thread was stopped by a signal. + int stop_signo = 0; + const bool stopped_by_signal = linux_thread_p->IsStopped (&stop_signo); + const char *signal_name = stopped_by_signal ? GetUnixSignals ().GetSignalAsCString (stop_signo) : "<not stopped by signal>"; + if (!signal_name) + signal_name = "<no-signal-name>"; + + log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " tid %" PRIu64 ", thread was already marked as a stopped state (state=%s, signal=%d (%s)), leaving stop signal as is", + __FUNCTION__, + GetID (), + linux_thread_p->GetID (), + StateAsCString (thread_state), + stop_signo, + signal_name); + } + } // Tell the thread state coordinator about the stop. NotifyThreadStop (thread_sp->GetID ()); |
