Adding support for stopping all threads of multithreaded inferiors on Linux.  Also adding multithreaded test cases.

llvm-svn: 182809
diff --git a/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp b/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp
index f2577e2..0ba8840 100644
--- a/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp
+++ b/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp
@@ -17,6 +17,7 @@
 #include <unistd.h>
 #include <sys/ptrace.h>
 #include <sys/socket.h>
+#include <sys/syscall.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 
@@ -52,6 +53,10 @@
   #define TRAP_HWBKPT 4
 #endif
 
+// Try to define a macro to encapsulate the tgkill syscall
+// fall back on kill() if tgkill isn't available
+#define tgkill(pid, tid, sig)  syscall(SYS_tgkill, pid, tid, sig)
+
 using namespace lldb_private;
 
 // FIXME: this code is host-dependent with respect to types and
@@ -724,7 +729,13 @@
         data = m_signo;
 
     if (PTRACE(PTRACE_CONT, m_tid, NULL, (void*)data, 0))
+    {
+        Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
+
+        if (log)
+            log->Printf ("ResumeOperation (%"  PRIu64 ") failed: %s", m_tid, strerror(errno));
         m_result = false;
+    }
     else
         m_result = true;
 }
@@ -1348,8 +1359,21 @@
     siginfo_t info;
     int ptrace_err;
 
+    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
+
+    if (exited)
+    {
+        if (log)
+            log->Printf ("ProcessMonitor::%s() got exit signal, tid = %"  PRIu64, __FUNCTION__, pid);
+        message = ProcessMessage::Exit(pid, status);
+        process->SendMessage(message);
+        return pid == process->GetID();
+    }
+
     if (!monitor->GetSignalInfo(pid, &info, ptrace_err)) {
         if (ptrace_err == EINVAL) {
+            if (log)
+                log->Printf ("ProcessMonitor::%s() resuming from group-stop", __FUNCTION__);
             // inferior process is in 'group-stop', so deliver SIGSTOP signal
             if (!monitor->Resume(pid, SIGSTOP)) {
               assert(0 && "SIGSTOP delivery failed while in 'group-stop' state");
@@ -1358,8 +1382,11 @@
         } else {
             // ptrace(GETSIGINFO) failed (but not due to group-stop). Most likely,
             // this means the child pid is gone (or not being debugged) therefore
-            // stop the monitor thread.
-            stop_monitoring = true;
+            // stop the monitor thread if this is the main pid.
+            if (log)
+                log->Printf ("ProcessMonitor::%s() GetSignalInfo failed: %s, tid = %" PRIu64 ", signal = %d, status = %d", 
+                              __FUNCTION__, strerror(ptrace_err), pid, signal, status);
+            stop_monitoring = pid == monitor->m_process->GetID();
         }
     }
     else {
@@ -1375,7 +1402,7 @@
         }
 
         process->SendMessage(message);
-        stop_monitoring = !process->IsAlive();
+        stop_monitoring = false;
     }
 
     return stop_monitoring;
@@ -1387,6 +1414,8 @@
 {
     ProcessMessage message;
 
+    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
+
     assert(monitor);
     assert(info && info->si_signo == SIGTRAP && "Unexpected child signal!");
 
@@ -1403,6 +1432,9 @@
 
     case (SIGTRAP | (PTRACE_EVENT_CLONE << 8)):
     {
+        if (log)
+            log->Printf ("ProcessMonitor::%s() received thread creation event, code = %d", __FUNCTION__, info->si_code ^ SIGTRAP);
+
         unsigned long tid = 0;
         if (!monitor->GetEventMessage(pid, &tid))
             tid = -1;
@@ -1417,27 +1449,35 @@
 
     case (SIGTRAP | (PTRACE_EVENT_EXIT << 8)):
     {
-        // The inferior process is about to exit.  Maintain the process in a
-        // state of "limbo" until we are explicitly commanded to detach,
-        // destroy, resume, etc.
+        // The inferior process or one of its threads is about to exit.
+        // Maintain the process or thread in a state of "limbo" until we are
+        // explicitly commanded to detach, destroy, resume, etc.
         unsigned long data = 0;
         if (!monitor->GetEventMessage(pid, &data))
             data = -1;
+        if (log)
+            log->Printf ("ProcessMonitor::%s() received exit event, data = %lx, pid = %" PRIu64, __FUNCTION__, data, pid);
         message = ProcessMessage::Limbo(pid, (data >> 8));
         break;
     }
 
     case 0:
     case TRAP_TRACE:
+        if (log)
+            log->Printf ("ProcessMonitor::%s() received trace event, pid = %" PRIu64, __FUNCTION__, pid);
         message = ProcessMessage::Trace(pid);
         break;
 
     case SI_KERNEL:
     case TRAP_BRKPT:
+        if (log)
+            log->Printf ("ProcessMonitor::%s() received breakpoint event, pid = %" PRIu64, __FUNCTION__, pid);
         message = ProcessMessage::Break(pid);
         break;
 
     case TRAP_HWBKPT:
+        if (log)
+            log->Printf ("ProcessMonitor::%s() received watchpoint event, pid = %" PRIu64, __FUNCTION__, pid);
         message = ProcessMessage::Watch(pid, (lldb::addr_t)info->si_addr);
         break;
     }
@@ -1452,6 +1492,8 @@
     ProcessMessage message;
     int signo = info->si_signo;
 
+    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
+
     // POSIX says that process behaviour is undefined after it ignores a SIGFPE,
     // SIGILL, SIGSEGV, or SIGBUS *unless* that signal was generated by a
     // kill(2) or raise(3).  Similarly for tgkill(2) on Linux.
@@ -1462,12 +1504,22 @@
     // Similarly, ACK signals generated by this monitor.
     if (info->si_code == SI_TKILL || info->si_code == SI_USER)
     {
+        if (log)
+            log->Printf ("ProcessMonitor::%s() received signal %s with code %s, pid = %" PRIu64,
+                            __FUNCTION__,
+                            monitor->m_process->GetUnixSignals().GetSignalAsCString (signo),
+                            (info->si_code == SI_TKILL ? "SI_TKILL" : "SI_USER"),
+                            info->si_pid);
+
         if (info->si_pid == getpid())
             return ProcessMessage::SignalDelivered(pid, signo);
         else
             return ProcessMessage::Signal(pid, signo);
     }
 
+    if (log)
+        log->Printf ("ProcessMonitor::%s() received signal %s", __FUNCTION__, monitor->m_process->GetUnixSignals().GetSignalAsCString (signo));
+
     if (signo == SIGSEGV) {
         lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
         ProcessMessage::CrashReason reason = GetCrashReasonForSIGSEGV(info);
@@ -1497,6 +1549,144 @@
     return ProcessMessage::Signal(pid, signo);
 }
 
+bool
+ProcessMonitor::StopThread(lldb::tid_t tid)
+{
+    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
+
+    // FIXME: Try to use tgkill or tkill
+    int ret = tgkill(m_pid, tid, SIGSTOP);
+    if (log)
+        log->Printf ("ProcessMonitor::%s(bp) stopping thread, tid = %" PRIu64 ", ret = %d", __FUNCTION__, tid, ret);
+
+    // This can happen if a thread exited while we were trying to stop it.  That's OK.
+    // We'll get the signal for that later.
+    if (ret < 0)
+        return false;
+
+    // Wait for the thread to stop
+    while (true)
+    {
+        int status = -1;
+        if (log)
+            log->Printf ("ProcessMonitor::%s(bp) waitpid...", __FUNCTION__);
+        lldb::pid_t wait_pid = ::waitpid (-1*m_pid, &status, __WALL);
+        if (log)
+            log->Printf ("ProcessMonitor::%s(bp) waitpid, pid = %" PRIu64 ", status = %d", __FUNCTION__, wait_pid, status);
+
+        if (wait_pid == -1)
+        {
+            // If we got interrupted by a signal (in our process, not the
+            // inferior) try again.
+            if (errno == EINTR)
+                continue;
+            else
+                return false; // This is bad, but there's nothing we can do.
+        }
+
+        // If this is a thread exit, we won't get any more information.
+        if (WIFEXITED(status))
+        {
+            m_process->SendMessage(ProcessMessage::Exit(wait_pid, WEXITSTATUS(status)));
+            if (wait_pid == tid)
+                return true;
+            continue;
+        }
+
+        siginfo_t info;
+        int ptrace_err;
+        if (!GetSignalInfo(wait_pid, &info, ptrace_err))
+        {
+            if (log)
+            {
+                log->Printf ("ProcessMonitor::%s() GetSignalInfo failed.", __FUNCTION__);
+
+                // This would be a particularly interesting case
+                if (ptrace_err == EINVAL)
+                    log->Printf ("ProcessMonitor::%s() in group-stop", __FUNCTION__);
+            }
+            return false;
+        }
+
+        // Handle events from other threads
+        if (log)
+            log->Printf ("ProcessMonitor::%s(bp) handling event, tid == %d", __FUNCTION__, wait_pid);
+
+        ProcessMessage message;
+        if (info.si_signo == SIGTRAP)
+            message = MonitorSIGTRAP(this, &info, wait_pid);
+        else
+            message = MonitorSignal(this, &info, wait_pid);
+
+        POSIXThread *thread = static_cast<POSIXThread*>(m_process->GetThreadList().FindThreadByID(wait_pid).get());
+
+        // When a new thread is created, we may get a SIGSTOP for the new thread
+        // just before we get the SIGTRAP that we use to add the thread to our
+        // process thread list.  We don't need to worry about that signal here.
+        assert(thread || message.GetKind() == ProcessMessage::eSignalMessage);
+
+        if (!thread)
+        {
+            m_process->SendMessage(message);
+            continue;
+        }
+
+        switch (message.GetKind())
+        {
+            case ProcessMessage::eInvalidMessage:
+                break;
+
+            // These need special handling because we don't want to send a
+            // resume even if we already sent a SIGSTOP to this thread. In
+            // this case the resume will cause the thread to disappear.  It is
+            // unlikely that we'll ever get eExitMessage here, but the same
+            // reasoning applies.
+            case ProcessMessage::eLimboMessage:
+            case ProcessMessage::eExitMessage:
+                if (log)
+                    log->Printf ("ProcessMonitor::%s(bp) handling message", __FUNCTION__);
+                // SendMessage will set the thread state as needed.
+                m_process->SendMessage(message);
+                // If this is the thread we're waiting for, stop waiting. Even
+                // though this wasn't the signal we expected, it's the last
+                // signal we'll see while this thread is alive.
+                if (wait_pid == tid)
+                    return true;
+                break;
+
+            case ProcessMessage::eSignalDeliveredMessage:
+                // This is the stop we're expecting.
+                if (wait_pid == tid && WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP && info.si_code == SI_TKILL)
+                {
+                    if (log)
+                        log->Printf ("ProcessMonitor::%s(bp) received signal, done waiting", __FUNCTION__);
+                    thread->SetState(lldb::eStateStopped);
+                    return true;
+                }
+                // else fall-through
+            case ProcessMessage::eSignalMessage:
+            case ProcessMessage::eBreakpointMessage:
+            case ProcessMessage::eTraceMessage:
+            case ProcessMessage::eWatchpointMessage:
+            case ProcessMessage::eCrashMessage:
+            case ProcessMessage::eNewThreadMessage:
+                if (log)
+                    log->Printf ("ProcessMonitor::%s(bp) handling message", __FUNCTION__);
+                // SendMessage will set the thread state as needed.
+                m_process->SendMessage(message);
+                // This isn't the stop we were expecting, but the thread is
+                // stopped. SendMessage will handle processing of this event,
+                // but we need to resume here to get the stop we are waiting
+                // for (otherwise the thread will stop again immediately when
+                // we try to resume).
+                if (wait_pid == tid)
+                    Resume(wait_pid, eResumeSignalNone);
+                break;
+        }
+    }
+    return false;
+}
+
 ProcessMessage::CrashReason
 ProcessMonitor::GetCrashReasonForSIGSEGV(const siginfo_t *info)
 {
@@ -1808,8 +1998,15 @@
 ProcessMonitor::Resume(lldb::tid_t tid, uint32_t signo)
 {
     bool result;
+    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
+
+    if (log)
+        log->Printf ("ProcessMonitor::%s() resuming thread = %"  PRIu64 " with signal %s", __FUNCTION__, tid,
+                                 m_process->GetUnixSignals().GetSignalAsCString (signo));
     ResumeOperation op(tid, signo, result);
     DoOperation(&op);
+    if (log)
+        log->Printf ("ProcessMonitor::%s() resuming result = %s", __FUNCTION__, result ? "true" : "false");
     return result;
 }