Add initial support to trace spawned threads in a process on Linux.



git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@171864 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Process/Linux/ProcessLinux.cpp b/source/Plugins/Process/Linux/ProcessLinux.cpp
index 6a766d7..6118a09 100644
--- a/source/Plugins/Process/Linux/ProcessLinux.cpp
+++ b/source/Plugins/Process/Linux/ProcessLinux.cpp
@@ -97,22 +97,7 @@
 bool
 ProcessLinux::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
 {
-    LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
-    if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
-        log->Printf ("ProcessLinux::%s() (pid = %" PRIu64 ")", __FUNCTION__, GetID());
-
-    // Update the process thread list with this new thread.
-    // FIXME: We should be using tid, not pid.
-    assert(m_monitor);
-    ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
-    if (!thread_sp) {
-        thread_sp.reset(new POSIXThread(*this, GetID()));
-    }
-
-    if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
-        log->Printf ("ProcessLinux::%s() updated pid = %" PRIu64, __FUNCTION__, GetID());
-    new_thread_list.AddThread(thread_sp);
-
+    new_thread_list = old_thread_list;
     return new_thread_list.GetSize(false) > 0;
 }
 
diff --git a/source/Plugins/Process/Linux/ProcessMonitor.cpp b/source/Plugins/Process/Linux/ProcessMonitor.cpp
index b71f0f9..f36a9ee 100644
--- a/source/Plugins/Process/Linux/ProcessMonitor.cpp
+++ b/source/Plugins/Process/Linux/ProcessMonitor.cpp
@@ -985,6 +985,7 @@
     const size_t err_len = 1024;
     char err_str[err_len];
     lldb::pid_t pid;
+    long ptrace_opts = 0;
 
     lldb::ThreadSP inferior;
     LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
@@ -1102,7 +1103,12 @@
 
     // Have the child raise an event on exit.  This is used to keep the child in
     // limbo until it is destroyed.
-    if (PTRACE(PTRACE_SETOPTIONS, pid, NULL, (void*)PTRACE_O_TRACEEXIT) < 0)
+    ptrace_opts |= PTRACE_O_TRACEEXIT;
+
+    // Have the tracer trace threads which spawn in the inferior process.
+    ptrace_opts |= PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACECLONE;
+
+    if (PTRACE(PTRACE_SETOPTIONS, pid, NULL, (void*)ptrace_opts) < 0)
     {
         args->m_error.SetErrorToErrno();
         goto FINISH;
@@ -1282,6 +1288,17 @@
         assert(false && "Unexpected SIGTRAP code!");
         break;
 
+    case (SIGTRAP | (PTRACE_EVENT_FORK << 8)):
+    case (SIGTRAP | (PTRACE_EVENT_VFORK << 8)):
+    case (SIGTRAP | (PTRACE_EVENT_CLONE << 8)):
+    {
+        unsigned long tid = 0;
+        if (!monitor->GetEventMessage(pid, &tid))
+            tid = -1;
+        message = ProcessMessage::NewThread(pid, tid);
+        break;
+    }
+
     case (SIGTRAP | (PTRACE_EVENT_EXIT << 8)):
     {
         // The inferior process is about to exit.  Maintain the process in a