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 ());


_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits

Reply via email to