[Lldb-commits] [lldb] r227916 - Added code to prevent "administrative stop" from overwriting a real stop reason.

Chaoren Lin chaorenl at google.com
Mon Feb 2 17:50:58 PST 2015


Author: chaoren
Date: Mon Feb  2 19:50:57 2015
New Revision: 227916

URL: http://llvm.org/viewvc/llvm-project?rev=227916&view=rev
Log:
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.

Modified:
    lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp

Modified: lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp?rev=227916&r1=227915&r2=227916&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp Mon Feb  2 19:50:57 2015
@@ -2521,11 +2521,44 @@ NativeProcessLinux::MonitorSignal(const
                              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 ());





More information about the lldb-commits mailing list