Remove shared_pointer from NativeThreadProtocol

Summary:
The NativeThread class is useless without the containing process (and in
some places it is already assuming the process is always around). This
makes it clear that the NativeProcessProtocol is the object owning the
threads, and makes the destruction order deterministic (first threads,
then process). The NativeProcess is the only thing holding a thread
unique_ptr, and methods that used to hand out thread shared pointers now
return raw pointers or references.

Reviewers: krytarowski, eugene

Subscribers: lldb-commits

Differential Revision: https://reviews.llvm.org/D35618

llvm-svn: 316007
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index a5dac2a..150de3c 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -305,10 +305,9 @@
   assert(m_sigchld_handle && status.Success());
 
   for (const auto &tid : tids) {
-    NativeThreadLinuxSP thread_sp = AddThread(tid);
-    assert(thread_sp && "AddThread() returned a nullptr thread");
-    thread_sp->SetStoppedBySignal(SIGSTOP);
-    ThreadWasCreated(*thread_sp);
+    NativeThreadLinux &thread = AddThread(tid);
+    thread.SetStoppedBySignal(SIGSTOP);
+    ThreadWasCreated(thread);
   }
 
   // Let our process instance know the thread has stopped.
@@ -478,11 +477,11 @@
     LLDB_LOG(log, "tid {0}, si_code: {1}, si_pid: {2}", pid, info.si_code,
              info.si_pid);
 
-    auto thread_sp = AddThread(pid);
+    NativeThreadLinux &thread = AddThread(pid);
 
     // Resume the newly created thread.
-    ResumeThread(*thread_sp, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
-    ThreadWasCreated(*thread_sp);
+    ResumeThread(thread, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
+    ThreadWasCreated(thread);
     return;
   }
 
@@ -549,12 +548,9 @@
 void NativeProcessLinux::WaitForNewThread(::pid_t tid) {
   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
 
-  NativeThreadLinuxSP new_thread_sp = GetThreadByID(tid);
-
-  if (new_thread_sp) {
+  if (GetThreadByID(tid)) {
     // We are already tracking the thread - we got the event on the new thread
-    // (see
-    // MonitorSignal) before this one. We are done.
+    // (see MonitorSignal) before this one. We are done.
     return;
   }
 
@@ -587,10 +583,10 @@
   }
 
   LLDB_LOG(log, "pid = {0}: tracking new thread tid {1}", GetID(), tid);
-  new_thread_sp = AddThread(tid);
+  NativeThreadLinux &new_thread = AddThread(tid);
 
-  ResumeThread(*new_thread_sp, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
-  ThreadWasCreated(*new_thread_sp);
+  ResumeThread(new_thread, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
+  ThreadWasCreated(new_thread);
 }
 
 void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
@@ -630,7 +626,6 @@
   }
 
   case (SIGTRAP | (PTRACE_EVENT_EXEC << 8)): {
-    NativeThreadLinuxSP main_thread_sp;
     LLDB_LOG(log, "received exec event, code = {0}", info.si_code ^ SIGTRAP);
 
     // Exec clears any pending notifications.
@@ -640,44 +635,26 @@
     // which only copies the main thread.
     LLDB_LOG(log, "exec received, stop tracking all but main thread");
 
-    for (auto thread_sp : m_threads) {
-      const bool is_main_thread = thread_sp && thread_sp->GetID() == GetID();
-      if (is_main_thread) {
-        main_thread_sp = std::static_pointer_cast<NativeThreadLinux>(thread_sp);
-        LLDB_LOG(log, "found main thread with tid {0}, keeping",
-                 main_thread_sp->GetID());
-      } else {
-        LLDB_LOG(log, "discarding non-main-thread tid {0} due to exec",
-                 thread_sp->GetID());
-      }
+    for (auto i = m_threads.begin(); i != m_threads.end();) {
+      if ((*i)->GetID() == GetID())
+        i = m_threads.erase(i);
+      else
+        ++i;
     }
+    assert(m_threads.size() == 1);
+    auto *main_thread = static_cast<NativeThreadLinux *>(m_threads[0].get());
 
-    m_threads.clear();
-
-    if (main_thread_sp) {
-      m_threads.push_back(main_thread_sp);
-      SetCurrentThreadID(main_thread_sp->GetID());
-      main_thread_sp->SetStoppedByExec();
-    } else {
-      SetCurrentThreadID(LLDB_INVALID_THREAD_ID);
-      LLDB_LOG(log,
-               "pid {0} no main thread found, discarded all threads, "
-               "we're in a no-thread state!",
-               GetID());
-    }
+    SetCurrentThreadID(main_thread->GetID());
+    main_thread->SetStoppedByExec();
 
     // Tell coordinator about about the "new" (since exec) stopped main thread.
-    ThreadWasCreated(*main_thread_sp);
+    ThreadWasCreated(*main_thread);
 
     // 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(main_thread_sp->GetID());
+    StopRunningThreads(main_thread->GetID());
 
     break;
   }
@@ -1115,44 +1092,44 @@
   bool software_single_step = !SupportHardwareSingleStepping();
 
   if (software_single_step) {
-    for (auto thread_sp : m_threads) {
-      assert(thread_sp && "thread list should not contain NULL threads");
+    for (const auto &thread : m_threads) {
+      assert(thread && "thread list should not contain NULL threads");
 
       const ResumeAction *const action =
-          resume_actions.GetActionForThread(thread_sp->GetID(), true);
+          resume_actions.GetActionForThread(thread->GetID(), true);
       if (action == nullptr)
         continue;
 
       if (action->state == eStateStepping) {
         Status error = SetupSoftwareSingleStepping(
-            static_cast<NativeThreadLinux &>(*thread_sp));
+            static_cast<NativeThreadLinux &>(*thread));
         if (error.Fail())
           return error;
       }
     }
   }
 
-  for (auto thread_sp : m_threads) {
-    assert(thread_sp && "thread list should not contain NULL threads");
+  for (const auto &thread : m_threads) {
+    assert(thread && "thread list should not contain NULL threads");
 
     const ResumeAction *const action =
-        resume_actions.GetActionForThread(thread_sp->GetID(), true);
+        resume_actions.GetActionForThread(thread->GetID(), true);
 
     if (action == nullptr) {
       LLDB_LOG(log, "no action specified for pid {0} tid {1}", GetID(),
-               thread_sp->GetID());
+               thread->GetID());
       continue;
     }
 
     LLDB_LOG(log, "processing resume action state {0} for pid {1} tid {2}",
-             action->state, GetID(), thread_sp->GetID());
+             action->state, GetID(), thread->GetID());
 
     switch (action->state) {
     case eStateRunning:
     case eStateStepping: {
       // Run the thread, possibly feeding it the signal.
       const int signo = action->signal;
-      ResumeThread(static_cast<NativeThreadLinux &>(*thread_sp), action->state,
+      ResumeThread(static_cast<NativeThreadLinux &>(*thread), action->state,
                    signo);
       break;
     }
@@ -1165,7 +1142,7 @@
       return Status("NativeProcessLinux::%s (): unexpected state %s specified "
                     "for pid %" PRIu64 ", tid %" PRIu64,
                     __FUNCTION__, StateAsCString(action->state), GetID(),
-                    thread_sp->GetID());
+                    thread->GetID());
     }
   }
 
@@ -1191,8 +1168,8 @@
   if (GetID() == LLDB_INVALID_PROCESS_ID)
     return error;
 
-  for (auto thread_sp : m_threads) {
-    Status e = Detach(thread_sp->GetID());
+  for (const auto &thread : m_threads) {
+    Status e = Detach(thread->GetID());
     if (e.Fail())
       error =
           e; // Save the error, but still attempt to detach from other threads.
@@ -1222,29 +1199,25 @@
   // the chosen thread that will be the stop-reason thread.
   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
 
-  NativeThreadProtocolSP running_thread_sp;
-  NativeThreadProtocolSP stopped_thread_sp;
+  NativeThreadProtocol *running_thread = nullptr;
+  NativeThreadProtocol *stopped_thread = nullptr;
 
   LLDB_LOG(log, "selecting running thread for interrupt target");
-  for (auto thread_sp : m_threads) {
-    // The thread shouldn't be null but lets just cover that here.
-    if (!thread_sp)
-      continue;
-
+  for (const auto &thread : m_threads) {
     // If we have a running or stepping thread, we'll call that the
     // target of the interrupt.
-    const auto thread_state = thread_sp->GetState();
+    const auto thread_state = thread->GetState();
     if (thread_state == eStateRunning || thread_state == eStateStepping) {
-      running_thread_sp = thread_sp;
+      running_thread = thread.get();
       break;
-    } else if (!stopped_thread_sp && StateIsStoppedState(thread_state, true)) {
+    } else if (!stopped_thread && StateIsStoppedState(thread_state, true)) {
       // Remember the first non-dead stopped thread.  We'll use that as a backup
       // if there are no running threads.
-      stopped_thread_sp = thread_sp;
+      stopped_thread = thread.get();
     }
   }
 
-  if (!running_thread_sp && !stopped_thread_sp) {
+  if (!running_thread && !stopped_thread) {
     Status error("found no running/stepping or live stopped threads as target "
                  "for interrupt");
     LLDB_LOG(log, "skipping due to error: {0}", error);
@@ -1252,14 +1225,14 @@
     return error;
   }
 
-  NativeThreadProtocolSP deferred_signal_thread_sp =
-      running_thread_sp ? running_thread_sp : stopped_thread_sp;
+  NativeThreadProtocol *deferred_signal_thread =
+      running_thread ? running_thread : stopped_thread;
 
   LLDB_LOG(log, "pid {0} {1} tid {2} chosen for interrupt target", GetID(),
-           running_thread_sp ? "running" : "stopped",
-           deferred_signal_thread_sp->GetID());
+           running_thread ? "running" : "stopped",
+           deferred_signal_thread->GetID());
 
-  StopRunningThreads(deferred_signal_thread_sp->GetID());
+  StopRunningThreads(deferred_signal_thread->GetID());
 
   return Status();
 }
@@ -1975,9 +1948,9 @@
 }
 
 bool NativeProcessLinux::HasThreadNoLock(lldb::tid_t thread_id) {
-  for (auto thread_sp : m_threads) {
-    assert(thread_sp && "thread list should not contain NULL threads");
-    if (thread_sp->GetID() == thread_id) {
+  for (const auto &thread : m_threads) {
+    assert(thread && "thread list should not contain NULL threads");
+    if (thread->GetID() == thread_id) {
       // We have this thread.
       return true;
     }
@@ -2006,7 +1979,7 @@
   return found;
 }
 
-NativeThreadLinuxSP NativeProcessLinux::AddThread(lldb::tid_t thread_id) {
+NativeThreadLinux &NativeProcessLinux::AddThread(lldb::tid_t thread_id) {
   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
   LLDB_LOG(log, "pid {0} adding thread with tid {1}", GetID(), thread_id);
 
@@ -2017,8 +1990,7 @@
   if (m_threads.empty())
     SetCurrentThreadID(thread_id);
 
-  auto thread_sp = std::make_shared<NativeThreadLinux>(*this, thread_id);
-  m_threads.push_back(thread_sp);
+  m_threads.push_back(llvm::make_unique<NativeThreadLinux>(*this, thread_id));
 
   if (m_pt_proces_trace_id != LLDB_INVALID_UID) {
     auto traceMonitor = ProcessorTraceMonitor::Create(
@@ -2034,7 +2006,7 @@
     }
   }
 
-  return thread_sp;
+  return static_cast<NativeThreadLinux &>(*m_threads.back());
 }
 
 Status
@@ -2156,8 +2128,8 @@
   return Status("No load address found for specified file.");
 }
 
-NativeThreadLinuxSP NativeProcessLinux::GetThreadByID(lldb::tid_t tid) {
-  return std::static_pointer_cast<NativeThreadLinux>(
+NativeThreadLinux *NativeProcessLinux::GetThreadByID(lldb::tid_t tid) {
+  return static_cast<NativeThreadLinux *>(
       NativeProcessProtocol::GetThreadByID(tid));
 }
 
@@ -2212,9 +2184,9 @@
 
   // Request a stop for all the thread stops that need to be stopped
   // and are not already known to be stopped.
-  for (const auto &thread_sp : m_threads) {
-    if (StateIsRunningState(thread_sp->GetState()))
-      static_pointer_cast<NativeThreadLinux>(thread_sp)->RequestStop();
+  for (const auto &thread : m_threads) {
+    if (StateIsRunningState(thread->GetState()))
+      static_cast<NativeThreadLinux *>(thread.get())->RequestStop();
   }
 
   SignalIfAllThreadsStopped();