This revision was automatically updated to reflect the committed changes.
Closed by commit rL245831: [NativeProcessLinux] Pass around threads by 
reference (authored by labath).

Changed prior to commit:
  http://reviews.llvm.org/D12237?vs=32824&id=32937#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D12237

Files:
  lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp
  lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.h

Index: lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.h
===================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -225,25 +225,25 @@
         WaitForNewThread(::pid_t tid);
 
         void
-        MonitorSIGTRAP(const siginfo_t *info, lldb::pid_t pid);
+        MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thread);
 
         void
-        MonitorTrace(lldb::pid_t pid, const NativeThreadLinuxSP &thread_sp);
+        MonitorTrace(NativeThreadLinux &thread);
 
         void
-        MonitorBreakpoint(lldb::pid_t pid, const NativeThreadLinuxSP &thread_sp);
+        MonitorBreakpoint(NativeThreadLinux &thread);
 
         void
         MonitorWatchpoint(NativeThreadLinux &thread, uint32_t wp_index);
 
         void
-        MonitorSignal(const siginfo_t *info, lldb::pid_t pid, bool exited);
+        MonitorSignal(const siginfo_t &info, NativeThreadLinux &thread, bool exited);
 
         bool
         SupportHardwareSingleStepping() const;
 
         Error
-        SetupSoftwareSingleStepping(NativeThreadProtocolSP thread_sp);
+        SetupSoftwareSingleStepping(NativeThreadLinux &thread);
 
 #if 0
         static ::ProcessMessage::CrashReason
@@ -262,20 +262,17 @@
         bool
         HasThreadNoLock (lldb::tid_t thread_id);
 
-        NativeThreadProtocolSP
-        MaybeGetThreadNoLock (lldb::tid_t thread_id);
-
         bool
         StopTrackingThread (lldb::tid_t thread_id);
 
         NativeThreadLinuxSP
         AddThread (lldb::tid_t thread_id);
 
         Error
-        GetSoftwareBreakpointPCOffset (NativeRegisterContextSP context_sp, uint32_t &actual_opcode_size);
+        GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size);
 
         Error
-        FixupBreakpointPCAsNeeded(const NativeThreadLinuxSP &thread_sp);
+        FixupBreakpointPCAsNeeded(NativeThreadLinux &thread);
 
         /// Writes a siginfo_t structure corresponding to the given thread ID to the
         /// memory region pointed to by @p siginfo.
@@ -317,7 +314,7 @@
         // Resume the given thread, optionally passing it the given signal. The type of resume
         // operation (continue, single-step) depends on the state parameter.
         Error
-        ResumeThread(const NativeThreadLinuxSP &thread_sp, lldb::StateType state, int signo);
+        ResumeThread(NativeThreadLinux &thread, lldb::StateType state, int signo);
 
         void
         ThreadWasCreated(NativeThreadLinux &thread);
Index: lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp
===================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -988,20 +988,47 @@
         return;
     }
 
-    // Get details on the signal raised.
     siginfo_t info;
-    const auto err = GetSignalInfo(pid, &info);
-    if (err.Success())
+    const auto info_err = GetSignalInfo(pid, &info);
+    auto thread_sp = GetThreadByID(pid);
+
+    if (! thread_sp)
+    {
+        // Normally, the only situation when we cannot find the thread is if we have just
+        // received a new thread notification. This is indicated by GetSignalInfo() returning
+        // si_code == SI_USER and si_pid == 0
+        if (log)
+            log->Printf("NativeProcessLinux::%s received notification about an unknown tid %" PRIu64 ".", __FUNCTION__, pid);
+
+        if (info_err.Fail())
+        {
+            if (log)
+                log->Printf("NativeProcessLinux::%s (tid %" PRIu64 ") GetSignalInfo failed (%s). Ingoring this notification.", __FUNCTION__, pid, info_err.AsCString());
+            return;
+        }
+
+        if (log && (info.si_code != SI_USER || info.si_pid != 0))
+            log->Printf("NativeProcessLinux::%s (tid %" PRIu64 ") unexpected signal info (si_code: %d, si_pid: %d). Treating as a new thread notification anyway.", __FUNCTION__, pid, info.si_code, info.si_pid);
+
+        auto thread_sp = AddThread(pid);
+        // Resume the newly created thread.
+        ResumeThread(*thread_sp, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
+        ThreadWasCreated(*thread_sp);
+        return;
+    }
+
+    // Get details on the signal raised.
+    if (info_err.Success())
     {
         // We have retrieved the signal info.  Dispatch appropriately.
         if (info.si_signo == SIGTRAP)
-            MonitorSIGTRAP(&info, pid);
+            MonitorSIGTRAP(info, *thread_sp);
         else
-            MonitorSignal(&info, pid, exited);
+            MonitorSignal(info, *thread_sp, exited);
     }
     else
     {
-        if (err.GetError() == EINVAL)
+        if (info_err.GetError() == EINVAL)
         {
             // This is a group stop reception for this tid.
             // We can reach here if we reinject SIGSTOP, SIGSTP, SIGTTIN or SIGTTOU into the
@@ -1013,7 +1040,7 @@
             // correctly for all signals.
             if (log)
                 log->Printf("NativeProcessLinux::%s received a group stop for pid %" PRIu64 " tid %" PRIu64 ". Transparent handling of group stops not supported, resuming the thread.", __FUNCTION__, GetID (), pid);
-            Resume(pid, signal);
+            ResumeThread(*thread_sp, thread_sp->GetState(), LLDB_INVALID_SIGNAL_NUMBER);
         }
         else
         {
@@ -1028,7 +1055,7 @@
 
             if (log)
                 log->Printf ("NativeProcessLinux::%s GetSignalInfo failed: %s, tid = %" PRIu64 ", signal = %d, status = %d (%s, %s, %s)",
-                             __FUNCTION__, err.AsCString(), pid, signal, status, err.GetError() == ESRCH ? "thread/process killed" : "unknown reason", is_main_thread ? "is main thread" : "is not main thread", thread_found ? "thread metadata removed" : "thread metadata not found");
+                             __FUNCTION__, info_err.AsCString(), pid, signal, status, info_err.GetError() == ESRCH ? "thread/process killed" : "unknown reason", is_main_thread ? "is main thread" : "is not main thread", thread_found ? "thread metadata removed" : "thread metadata not found");
 
             if (is_main_thread)
             {
@@ -1111,31 +1138,21 @@
                  __FUNCTION__, GetID (), tid);
 
     new_thread_sp = AddThread(tid);
-    ResumeThread(new_thread_sp, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
+    ResumeThread(*new_thread_sp, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
     ThreadWasCreated(*new_thread_sp);
 }
 
 void
-NativeProcessLinux::MonitorSIGTRAP(const siginfo_t *info, lldb::pid_t pid)
+NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thread)
 {
     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
-    const bool is_main_thread = (pid == GetID ());
+    const bool is_main_thread = (thread.GetID() == GetID ());
 
-    assert(info && info->si_signo == SIGTRAP && "Unexpected child signal!");
-    if (!info)
-        return;
+    assert(info.si_signo == SIGTRAP && "Unexpected child signal!");
 
     Mutex::Locker locker (m_threads_mutex);
 
-    // See if we can find a thread for this signal.
-    NativeThreadLinuxSP thread_sp = GetThreadByID(pid);
-    if (!thread_sp)
-    {
-        if (log)
-            log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " no thread found for tid %" PRIu64, __FUNCTION__, GetID (), pid);
-    }
-
-    switch (info->si_code)
+    switch (info.si_code)
     {
     // TODO: these two cases are required if we want to support tracing of the inferiors' children.  We'd need this to debug a monitor.
     // case (SIGTRAP | (PTRACE_EVENT_FORK << 8)):
@@ -1150,22 +1167,22 @@
         // here.
 
         unsigned long event_message = 0;
-        if (GetEventMessage (pid, &event_message).Fail())
+        if (GetEventMessage(thread.GetID(), &event_message).Fail())
         {
             if (log)
-                log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " received thread creation event but GetEventMessage failed so we don't know the new tid", __FUNCTION__, pid);
+                log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " received thread creation event but GetEventMessage failed so we don't know the new tid", __FUNCTION__, thread.GetID());
         } else 
             WaitForNewThread(event_message);
 
-        ResumeThread(thread_sp, thread_sp->GetState(), LLDB_INVALID_SIGNAL_NUMBER);
+        ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
         break;
     }
 
     case (SIGTRAP | (PTRACE_EVENT_EXEC << 8)):
     {
         NativeThreadLinuxSP main_thread_sp;
         if (log)
-            log->Printf ("NativeProcessLinux::%s() received exec event, code = %d", __FUNCTION__, info->si_code ^ SIGTRAP);
+            log->Printf ("NativeProcessLinux::%s() received exec event, code = %d", __FUNCTION__, info.si_code ^ SIGTRAP);
 
         // Exec clears any pending notifications.
         m_pending_notification_tid = LLDB_INVALID_THREAD_ID;
@@ -1208,16 +1225,14 @@
         // Tell coordinator about about the "new" (since exec) stopped main thread.
         ThreadWasCreated(*main_thread_sp);
 
-        // NOTE: ideally these next statements would execute at the same time as the coordinator thread create was executed.
-        // Consider a handler that can execute when that happens.
         // Let our delegate know we have just exec'd.
         NotifyDidExec ();
 
         // If we have a main thread, indicate we are stopped.
         assert (main_thread_sp && "exec called during ptraced process but no main thread metadata tracked");
 
         // Let the process know we're stopped.
-        StopRunningThreads (pid);
+        StopRunningThreads(main_thread_sp->GetID());
 
         break;
     }
@@ -1230,147 +1245,129 @@
         // here.
 
         unsigned long data = 0;
-        if (GetEventMessage(pid, &data).Fail())
+        if (GetEventMessage(thread.GetID(), &data).Fail())
             data = -1;
 
         if (log)
         {
             log->Printf ("NativeProcessLinux::%s() received PTRACE_EVENT_EXIT, data = %lx (WIFEXITED=%s,WIFSIGNALED=%s), pid = %" PRIu64 " (%s)",
                          __FUNCTION__,
                          data, WIFEXITED (data) ? "true" : "false", WIFSIGNALED (data) ? "true" : "false",
-                         pid,
+                         thread.GetID(),
                     is_main_thread ? "is main thread" : "not main thread");
         }
 
         if (is_main_thread)
         {
             SetExitStatus (convert_pid_status_to_exit_type (data), convert_pid_status_to_return_code (data), nullptr, true);
         }
 
-        ResumeThread(thread_sp, thread_sp->GetState(), LLDB_INVALID_SIGNAL_NUMBER);
+        ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
 
         break;
     }
 
     case 0:
     case TRAP_TRACE:  // We receive this on single stepping.
     case TRAP_HWBKPT: // We receive this on watchpoint hit
-        if (thread_sp)
+    {
+        // If a watchpoint was hit, report it
+        uint32_t wp_index;
+        Error error = thread.GetRegisterContext()->GetWatchpointHitIndex(wp_index, (lldb::addr_t)info.si_addr);
+        if (error.Fail() && log)
+            log->Printf("NativeProcessLinux::%s() "
+                        "received error while checking for watchpoint hits, "
+                        "pid = %" PRIu64 " error = %s",
+                        __FUNCTION__, thread.GetID(), error.AsCString());
+        if (wp_index != LLDB_INVALID_INDEX32)
         {
-            // If a watchpoint was hit, report it
-            uint32_t wp_index;
-            Error error = thread_sp->GetRegisterContext()->GetWatchpointHitIndex(wp_index, (lldb::addr_t)info->si_addr);
-            if (error.Fail() && log)
-                log->Printf("NativeProcessLinux::%s() "
-                            "received error while checking for watchpoint hits, "
-                            "pid = %" PRIu64 " error = %s",
-                            __FUNCTION__, pid, error.AsCString());
-            if (wp_index != LLDB_INVALID_INDEX32)
-            {
-                MonitorWatchpoint(*thread_sp, wp_index);
-                break;
-            }
+            MonitorWatchpoint(thread, wp_index);
+            break;
         }
+
         // Otherwise, report step over
-        MonitorTrace(pid, thread_sp);
+        MonitorTrace(thread);
         break;
+    }
 
     case SI_KERNEL:
 #if defined __mips__
         // For mips there is no special signal for watchpoint
         // So we check for watchpoint in kernel trap
-        if (thread_sp)
+    {
+        // If a watchpoint was hit, report it
+        uint32_t wp_index;
+        Error error = thread.GetRegisterContext()->GetWatchpointHitIndex(wp_index, LLDB_INVALID_ADDRESS);
+        if (error.Fail() && log)
+            log->Printf("NativeProcessLinux::%s() "
+                        "received error while checking for watchpoint hits, "
+                        "pid = %" PRIu64 " error = %s",
+                        __FUNCTION__, pid, error.AsCString());
+        if (wp_index != LLDB_INVALID_INDEX32)
         {
-            // If a watchpoint was hit, report it
-            uint32_t wp_index;
-            Error error = thread_sp->GetRegisterContext()->GetWatchpointHitIndex(wp_index, LLDB_INVALID_ADDRESS);
-            if (error.Fail() && log)
-                log->Printf("NativeProcessLinux::%s() "
-                            "received error while checking for watchpoint hits, "
-                            "pid = %" PRIu64 " error = %s",
-                            __FUNCTION__, pid, error.AsCString());
-            if (wp_index != LLDB_INVALID_INDEX32)
-            {
-                MonitorWatchpoint(*thread_sp, wp_index);
-                break;
-            }
+            MonitorWatchpoint(thread, wp_index);
+            break;
         }
+    }
         // NO BREAK
 #endif
     case TRAP_BRKPT:
-        MonitorBreakpoint(pid, thread_sp);
+        MonitorBreakpoint(thread);
         break;
 
     case SIGTRAP:
     case (SIGTRAP | 0x80):
         if (log)
-            log->Printf ("NativeProcessLinux::%s() received unknown SIGTRAP system call stop event, pid %" PRIu64 "tid %" PRIu64 ", resuming", __FUNCTION__, GetID (), pid);
+            log->Printf ("NativeProcessLinux::%s() received unknown SIGTRAP system call stop event, pid %" PRIu64 "tid %" PRIu64 ", resuming", __FUNCTION__, GetID (), thread.GetID());
 
         // Ignore these signals until we know more about them.
-        ResumeThread(thread_sp, thread_sp->GetState(), LLDB_INVALID_SIGNAL_NUMBER);
+        ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
         break;
 
     default:
         assert(false && "Unexpected SIGTRAP code!");
         if (log)
             log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 "tid %" PRIu64 " received unhandled SIGTRAP code: 0x%d",
-                    __FUNCTION__, GetID (), pid, info->si_code);
+                    __FUNCTION__, GetID(), thread.GetID(), info.si_code);
         break;
         
     }
 }
 
 void
-NativeProcessLinux::MonitorTrace(lldb::pid_t pid, const NativeThreadLinuxSP &thread_sp)
+NativeProcessLinux::MonitorTrace(NativeThreadLinux &thread)
 {
     Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
     if (log)
         log->Printf("NativeProcessLinux::%s() received trace event, pid = %" PRIu64 " (single stepping)",
-                __FUNCTION__, pid);
+                __FUNCTION__, thread.GetID());
 
     // This thread is currently stopped.
-    if (thread_sp)
-        thread_sp->SetStoppedByTrace();
+    thread.SetStoppedByTrace();
 
-    // Here we don't have to request the rest of the threads to stop or request a deferred stop.
-    // This would have already happened at the time the Resume() with step operation was signaled.
-    // At this point, we just need to say we stopped, and the deferred notifcation will fire off
-    // once all running threads have checked in as stopped.
-    SetCurrentThreadID(pid);
-    // Tell the process we have a stop (from software breakpoint).
-    StopRunningThreads(pid);
+    StopRunningThreads(thread.GetID());
 }
 
 void
-NativeProcessLinux::MonitorBreakpoint(lldb::pid_t pid, const NativeThreadLinuxSP &thread_sp)
+NativeProcessLinux::MonitorBreakpoint(NativeThreadLinux &thread)
 {
     Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_BREAKPOINTS));
     if (log)
         log->Printf("NativeProcessLinux::%s() received breakpoint event, pid = %" PRIu64,
-                __FUNCTION__, pid);
+                __FUNCTION__, thread.GetID());
 
     // Mark the thread as stopped at breakpoint.
-    if (thread_sp)
-    {
-        thread_sp->SetStoppedByBreakpoint();
-        Error error = FixupBreakpointPCAsNeeded(thread_sp);
-        if (error.Fail())
-            if (log)
-                log->Printf("NativeProcessLinux::%s() pid = %" PRIu64 " fixup: %s",
-                        __FUNCTION__, pid, error.AsCString());
-
-        if (m_threads_stepping_with_breakpoint.find(pid) != m_threads_stepping_with_breakpoint.end())
-            thread_sp->SetStoppedByTrace();
-    }
-    else
+    thread.SetStoppedByBreakpoint();
+    Error error = FixupBreakpointPCAsNeeded(thread);
+    if (error.Fail())
         if (log)
-            log->Printf("NativeProcessLinux::%s()  pid = %" PRIu64 ": "
-                    "warning, cannot process software breakpoint since no thread metadata",
-                    __FUNCTION__, pid);
+            log->Printf("NativeProcessLinux::%s() pid = %" PRIu64 " fixup: %s",
+                    __FUNCTION__, thread.GetID(), error.AsCString());
 
+    if (m_threads_stepping_with_breakpoint.find(thread.GetID()) != m_threads_stepping_with_breakpoint.end())
+        thread.SetStoppedByTrace();
 
-    // We need to tell all other running threads before we notify the delegate about this stop.
-    StopRunningThreads(pid);
+    StopRunningThreads(thread.GetID());
 }
 
 void
@@ -1391,14 +1388,10 @@
 }
 
 void
-NativeProcessLinux::MonitorSignal(const siginfo_t *info, lldb::pid_t pid, bool exited)
+NativeProcessLinux::MonitorSignal(const siginfo_t &info, NativeThreadLinux &thread, bool exited)
 {
-    assert (info && "null info");
-    if (!info)
-        return;
-
-    const int signo = info->si_signo;
-    const bool is_from_llgs = info->si_pid == getpid ();
+    const int signo = info.si_signo;
+    const bool is_from_llgs = info.si_pid == getpid ();
 
     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
 
@@ -1413,120 +1406,89 @@
 
     Mutex::Locker locker (m_threads_mutex);
 
-    // See if we can find a thread for this signal.
-    NativeThreadLinuxSP thread_sp = GetThreadByID(pid);
-    if (!thread_sp)
-    {
-        if (log)
-            log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " no thread found for tid %" PRIu64, __FUNCTION__, GetID (), pid);
-    }
-
     // Handle the signal.
-    if (info->si_code == SI_TKILL || info->si_code == SI_USER)
+    if (info.si_code == SI_TKILL || info.si_code == SI_USER)
     {
         if (log)
             log->Printf ("NativeProcessLinux::%s() received signal %s (%d) with code %s, (siginfo pid = %d (%s), waitpid pid = %" PRIu64 ")",
                             __FUNCTION__,
                             Host::GetSignalAsCString(signo),
                             signo,
-                            (info->si_code == SI_TKILL ? "SI_TKILL" : "SI_USER"),
-                            info->si_pid,
+                            (info.si_code == SI_TKILL ? "SI_TKILL" : "SI_USER"),
+                            info.si_pid,
                             is_from_llgs ? "from llgs" : "not from llgs",
-                            pid);
-    }
-
-    // Check for new thread notification.
-    if ((info->si_pid == 0) && (info->si_code == SI_USER))
-    {
-        // A new thread creation is being signaled. This is one of two parts that come in
-        // a non-deterministic order. This code handles the case where the new thread event comes
-        // before the event on the parent thread. For the opposite case see code in
-        // MonitorSIGTRAP.
-        if (log)
-            log->Printf ("NativeProcessLinux::%s() pid = %" PRIu64 " tid %" PRIu64 ": new thread notification",
-                     __FUNCTION__, GetID (), pid);
-
-        thread_sp = AddThread(pid);
-        assert (thread_sp.get() && "failed to create the tracking data for newly created inferior thread");
-        // We can now resume the newly created thread.
-        ResumeThread(thread_sp, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
-        ThreadWasCreated(*thread_sp);
-        // Done handling.
-        return;
+                            thread.GetID());
     }
 
     // Check for thread stop notification.
-    if (is_from_llgs && (info->si_code == SI_TKILL) && (signo == SIGSTOP))
+    if (is_from_llgs && (info.si_code == SI_TKILL) && (signo == SIGSTOP))
     {
         // This is a tgkill()-based stop.
-        if (thread_sp)
-        {
-            if (log)
-                log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " tid %" PRIu64 ", thread stopped",
-                             __FUNCTION__,
-                             GetID (),
-                             pid);
-
-            // 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.
-            const StateType thread_state = thread_sp->GetState();
-            if (!StateIsStoppedState (thread_state, false))
-            {
-                // An inferior thread has stopped because of a SIGSTOP we have sent it.
-                // Generally, these are not important stops and we don't want to report them as
-                // they are just used to stop other threads when one thread (the one with the
-                // *real* stop reason) hits a breakpoint (watchpoint, etc...). However, in the
-                // case of an asynchronous Interrupt(), this *is* the real stop reason, so we
-                // leave the signal intact if this is the thread that was chosen as the
-                // triggering thread.
-                if (m_pending_notification_tid != LLDB_INVALID_THREAD_ID)
-                {
-                    if (m_pending_notification_tid == pid)
-                        thread_sp->SetStoppedBySignal(SIGSTOP, info);
-                    else
-                        thread_sp->SetStoppedWithNoReason();
+        if (log)
+            log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " tid %" PRIu64 ", thread stopped",
+                         __FUNCTION__,
+                         GetID (),
+                         thread.GetID());
 
-                    SetCurrentThreadID (thread_sp->GetID ());
-                    SignalIfAllThreadsStopped();
-                }
+        // 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.
+        const StateType thread_state = thread.GetState();
+        if (!StateIsStoppedState (thread_state, false))
+        {
+            // An inferior thread has stopped because of a SIGSTOP we have sent it.
+            // Generally, these are not important stops and we don't want to report them as
+            // they are just used to stop other threads when one thread (the one with the
+            // *real* stop reason) hits a breakpoint (watchpoint, etc...). However, in the
+            // case of an asynchronous Interrupt(), this *is* the real stop reason, so we
+            // leave the signal intact if this is the thread that was chosen as the
+            // triggering thread.
+            if (m_pending_notification_tid != LLDB_INVALID_THREAD_ID)
+            {
+                if (m_pending_notification_tid == thread.GetID())
+                    thread.SetStoppedBySignal(SIGSTOP, &info);
                 else
-                {
-                    // We can end up here if stop was initiated by LLGS but by this time a
-                    // thread stop has occurred - maybe initiated by another event.
-                    Error error = ResumeThread(thread_sp, thread_sp->GetState(), 0);
-                    if (error.Fail() && log)
-                    {
-                        log->Printf("NativeProcessLinux::%s failed to resume thread tid  %" PRIu64 ": %s",
-                                __FUNCTION__, thread_sp->GetID(), error.AsCString());
-                    }
-                }
+                    thread.SetStoppedWithNoReason();
+
+                SetCurrentThreadID (thread.GetID ());
+                SignalIfAllThreadsStopped();
             }
             else
             {
-                if (log)
+                // We can end up here if stop was initiated by LLGS but by this time a
+                // thread stop has occurred - maybe initiated by another event.
+                Error error = ResumeThread(thread, thread.GetState(), 0);
+                if (error.Fail() && log)
                 {
-                    // Retrieve the signal name if the thread was stopped by a signal.
-                    int stop_signo = 0;
-                    const bool stopped_by_signal = thread_sp->IsStopped(&stop_signo);
-                    const char *signal_name = stopped_by_signal ? Host::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 (),
-                                 thread_sp->GetID(),
-                                 StateAsCString (thread_state),
-                                 stop_signo,
-                                 signal_name);
+                    log->Printf("NativeProcessLinux::%s failed to resume thread tid  %" PRIu64 ": %s",
+                            __FUNCTION__, thread.GetID(), error.AsCString());
                 }
-                SignalIfAllThreadsStopped();
             }
         }
+        else
+        {
+            if (log)
+            {
+                // Retrieve the signal name if the thread was stopped by a signal.
+                int stop_signo = 0;
+                const bool stopped_by_signal = thread.IsStopped(&stop_signo);
+                const char *signal_name = stopped_by_signal ? Host::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 (),
+                             thread.GetID(),
+                             StateAsCString (thread_state),
+                             stop_signo,
+                             signal_name);
+            }
+            SignalIfAllThreadsStopped();
+        }
 
         // Done handling.
         return;
@@ -1536,11 +1498,10 @@
         log->Printf ("NativeProcessLinux::%s() received signal %s", __FUNCTION__, Host::GetSignalAsCString(signo));
 
     // This thread is stopped.
-    if (thread_sp)
-        thread_sp->SetStoppedBySignal(signo, info);
+    thread.SetStoppedBySignal(signo, &info);
 
     // Send a stop to the debugger after we get all other threads to stop.
-    StopRunningThreads (pid);
+    StopRunningThreads(thread.GetID());
 }
 
 namespace {
@@ -1634,10 +1595,10 @@
 }
 
 Error
-NativeProcessLinux::SetupSoftwareSingleStepping(NativeThreadProtocolSP thread_sp)
+NativeProcessLinux::SetupSoftwareSingleStepping(NativeThreadLinux &thread)
 {
     Error error;
-    NativeRegisterContextSP register_context_sp = thread_sp->GetRegisterContext();
+    NativeRegisterContextSP register_context_sp = thread.GetRegisterContext();
 
     std::unique_ptr<EmulateInstruction> emulator_ap(
         EmulateInstruction::FindPlugin(m_arch, eInstructionTypePCModifying, nullptr));
@@ -1719,7 +1680,7 @@
     if (error.Fail())
         return error;
 
-    m_threads_stepping_with_breakpoint.insert({thread_sp->GetID(), next_pc});
+    m_threads_stepping_with_breakpoint.insert({thread.GetID(), next_pc});
 
     return Error();
 }
@@ -1757,7 +1718,7 @@
 
             if (action->state == eStateStepping)
             {
-                Error error = SetupSoftwareSingleStepping(thread_sp);
+                Error error = SetupSoftwareSingleStepping(static_cast<NativeThreadLinux &>(*thread_sp));
                 if (error.Fail())
                     return error;
             }
@@ -1791,7 +1752,7 @@
         {
             // Run the thread, possibly feeding it the signal.
             const int signo = action->signal;
-            ResumeThread(std::static_pointer_cast<NativeThreadLinux>(thread_sp), action->state, signo);
+            ResumeThread(static_cast<NativeThreadLinux &>(*thread_sp), action->state, signo);
             break;
         }
 
@@ -2267,7 +2228,7 @@
 }
 
 Error
-NativeProcessLinux::GetSoftwareBreakpointPCOffset (NativeRegisterContextSP context_sp, uint32_t &actual_opcode_size)
+NativeProcessLinux::GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size)
 {
     // FIXME put this behind a breakpoint protocol class that can be
     // set per architecture.  Need ARM, MIPS support here.
@@ -2770,20 +2731,6 @@
     return false;
 }
 
-NativeThreadProtocolSP
-NativeProcessLinux::MaybeGetThreadNoLock (lldb::tid_t thread_id)
-{
-    // CONSIDER organize threads by map - we can do better than linear.
-    for (auto thread_sp : m_threads)
-    {
-        if (thread_sp->GetID () == thread_id)
-            return thread_sp;
-    }
-
-    // We don't have this thread.
-    return NativeThreadProtocolSP ();
-}
-
 bool
 NativeProcessLinux::StopTrackingThread (lldb::tid_t thread_id)
 {
@@ -2837,22 +2784,14 @@
 }
 
 Error
-NativeProcessLinux::FixupBreakpointPCAsNeeded(const NativeThreadLinuxSP &thread_sp)
+NativeProcessLinux::FixupBreakpointPCAsNeeded(NativeThreadLinux &thread)
 {
     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
 
     Error error;
 
-    if (!thread_sp)
-    {
-        error.SetErrorString ("null thread_sp");
-        if (log)
-            log->Printf ("NativeProcessLinux::%s failed: %s", __FUNCTION__, error.AsCString ());
-        return error;
-    }
-
     // Find out the size of a breakpoint (might depend on where we are in the code).
-    NativeRegisterContextSP context_sp = thread_sp->GetRegisterContext();
+    NativeRegisterContextSP context_sp = thread.GetRegisterContext();
     if (!context_sp)
     {
         error.SetErrorString ("cannot get a NativeRegisterContext for the thread");
@@ -2862,7 +2801,7 @@
     }
 
     uint32_t breakpoint_size = 0;
-    error = GetSoftwareBreakpointPCOffset (context_sp, breakpoint_size);
+    error = GetSoftwareBreakpointPCOffset(breakpoint_size);
     if (error.Fail ())
     {
         if (log)
@@ -2919,13 +2858,13 @@
 
     // Change the program counter.
     if (log)
-        log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64 ": changing PC from 0x%" PRIx64 " to 0x%" PRIx64, __FUNCTION__, GetID(), thread_sp->GetID(), initial_pc_addr, breakpoint_addr);
+        log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64 ": changing PC from 0x%" PRIx64 " to 0x%" PRIx64, __FUNCTION__, GetID(), thread.GetID(), initial_pc_addr, breakpoint_addr);
 
     error = context_sp->SetPC (breakpoint_addr);
     if (error.Fail ())
     {
         if (log)
-            log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64 ": failed to set PC: %s", __FUNCTION__, GetID(), thread_sp->GetID(), error.AsCString ());
+            log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64 ": failed to set PC: %s", __FUNCTION__, GetID(), thread.GetID(), error.AsCString ());
         return error;
     }
 
@@ -3003,13 +2942,13 @@
 }
 
 Error
-NativeProcessLinux::ResumeThread(const NativeThreadLinuxSP &thread_sp, lldb::StateType state, int signo)
+NativeProcessLinux::ResumeThread(NativeThreadLinux &thread, lldb::StateType state, int signo)
 {
     Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD);
 
     if (log)
         log->Printf("NativeProcessLinux::%s (tid: %" PRIu64 ")",
-                __FUNCTION__, thread_sp->GetID());
+                __FUNCTION__, thread.GetID());
     
     // Before we do the resume below, first check if we have a pending
     // stop notification that is currently waiting for
@@ -3019,25 +2958,25 @@
     // out the pending stop notification.
     if (m_pending_notification_tid != LLDB_INVALID_THREAD_ID && log)
     {
-        log->Printf("NativeProcessLinux::%s about to resume tid %" PRIu64 " per explicit request but we have a pending stop notification (tid %" PRIu64 ") that is actively waiting for this thread to stop. Valid sequence of events?", __FUNCTION__, thread_sp->GetID(), m_pending_notification_tid);
+        log->Printf("NativeProcessLinux::%s about to resume tid %" PRIu64 " per explicit request but we have a pending stop notification (tid %" PRIu64 ") that is actively waiting for this thread to stop. Valid sequence of events?", __FUNCTION__, thread.GetID(), m_pending_notification_tid);
     }
 
     // Request a resume.  We expect this to be synchronous and the system
     // to reflect it is running after this completes.
     switch (state)
     {
     case eStateRunning:
     {
-        thread_sp->SetRunning();
-        const auto resume_result = Resume(thread_sp->GetID(), signo);
+        thread.SetRunning();
+        const auto resume_result = Resume(thread.GetID(), signo);
         if (resume_result.Success())
             SetState(eStateRunning, true);
         return resume_result;
     }
     case eStateStepping:
     {
-        thread_sp->SetStepping();
-        const auto step_result = SingleStep(thread_sp->GetID(), signo);
+        thread.SetStepping();
+        const auto step_result = SingleStep(thread.GetID(), signo);
         if (step_result.Success())
             SetState(eStateRunning, true);
         return step_result;
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to