[Lldb-commits] [lldb] r185442 - Sync parts of FreeBSD Process plugin with Linux

Ed Maste emaste at freebsd.org
Tue Jul 2 09:45:16 PDT 2013


Author: emaste
Date: Tue Jul  2 11:45:16 2013
New Revision: 185442

URL: http://llvm.org/viewvc/llvm-project?rev=185442&view=rev
Log:
Sync parts of FreeBSD Process plugin with Linux

* Use PseudoTerminal to fix stdio handling / passthrough to the inferior
  process.
* Add log messages equivalent to the Linux ones.
* Port changes relating to process creation / termination.

This revision contains changes equivalent to (parts of) SVN revisions
109318 142384 166055 168503 169645 177116 182809.

Modified:
    lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
    lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.h

Modified: lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp?rev=185442&r1=185441&r2=185442&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp (original)
+++ lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp Tue Jul  2 11:45:16 2013
@@ -11,6 +11,7 @@
 #include <errno.h>
 #include <poll.h>
 #include <string.h>
+#include <stdint.h>
 #include <unistd.h>
 #include <signal.h>
 #include <sys/ptrace.h>
@@ -474,7 +475,13 @@ ResumeOperation::Execute(ProcessMonitor
         data = m_signo;
 
     if (PTRACE(PT_CONTINUE, m_tid, (caddr_t)1, data))
+    {
+        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;
 }
@@ -601,7 +608,7 @@ KillOperation::Execute(ProcessMonitor *m
 }
 
 //------------------------------------------------------------------------------
-/// @class KillOperation
+/// @class DetachOperation
 /// @brief Implements ProcessMonitor::BringProcessIntoLimbo.
 class DetachOperation : public Operation
 {
@@ -725,7 +732,7 @@ WAIT_AGAIN:
     // Check that the launch was a success.
     if (!args->m_error.Success())
     {
-        StopLaunchOpThread();
+        StopOpThread();
         error = args->m_error;
         return;
     }
@@ -781,10 +788,10 @@ WAIT_AGAIN:
         }
     }
 
-    // Check that the launch was a success.
+    // Check that the attach was a success.
     if (!args->m_error.Success())
     {
-        StopAttachOpThread();
+        StopOpThread();
         error = args->m_error;
         return;
     }
@@ -819,18 +826,6 @@ ProcessMonitor::StartLaunchOpThread(Laun
         Host::ThreadCreate(g_thread_name, LaunchOpThread, args, &error);
 }
 
-void
-ProcessMonitor::StopLaunchOpThread()
-{
-    lldb::thread_result_t result;
-
-    if (!IS_VALID_LLDB_HOST_THREAD(m_operation_thread))
-        return;
-
-    Host::ThreadCancel(m_operation_thread, NULL);
-    Host::ThreadJoin(m_operation_thread, &result, NULL);
-}
-
 void *
 ProcessMonitor::LaunchOpThread(void *arg)
 {
@@ -857,14 +852,34 @@ ProcessMonitor::Launch(LaunchArgs *args)
     const char *stdout_path = args->m_stdout_path;
     const char *stderr_path = args->m_stderr_path;
     const char *working_dir = args->m_working_dir;
+
+    lldb_utility::PseudoTerminal terminal;
+    const size_t err_len = 1024;
+    char err_str[err_len];
     lldb::pid_t pid;
 
     lldb::ThreadSP inferior;
+    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
 
     // Propagate the environment if one is not supplied.
     if (envp == NULL || envp[0] == NULL)
         envp = const_cast<const char **>(environ);
 
+    // Pseudo terminal setup.
+    if (!terminal.OpenFirstAvailableMaster(O_RDWR | O_NOCTTY, err_str, err_len))
+    {
+        args->m_error.SetErrorToGenericError();
+        args->m_error.SetErrorString("Could not open controlling TTY.");
+        goto FINISH;
+    }
+
+    if ((pid = terminal.Fork(err_str, err_len)) == -1)
+    {
+        args->m_error.SetErrorToGenericError();
+        args->m_error.SetErrorString("Process fork failed.");
+        goto FINISH;
+    }
+
     // Recognized child exit status codes.
     enum {
         ePtraceFailed = 1,
@@ -875,8 +890,6 @@ ProcessMonitor::Launch(LaunchArgs *args)
         eExecFailed
     };
 
-    pid = fork();
-
     // Child process.
     if (pid == 0)
     {
@@ -968,10 +981,9 @@ ProcessMonitor::Launch(LaunchArgs *args)
         goto FINISH;
     }
 #endif
-    // XXX - Release the master terminal descriptor and pass it off to the
-    // XXX - ProcessMonitor instance.  Similarly stash the inferior pid.
-    // For now just use stdin fd
-    monitor->m_terminal_fd = ::dup(STDIN_FILENO);
+    // Release the master terminal descriptor and pass it off to the
+    // ProcessMonitor instance.  Similarly stash the inferior pid.
+    monitor->m_terminal_fd = terminal.ReleaseMasterFileDescriptor();
     monitor->m_pid = pid;
 
     // Set the terminal fd to be in non blocking mode (it simplifies the
@@ -982,6 +994,8 @@ ProcessMonitor::Launch(LaunchArgs *args)
 
     // Update the process thread list with this new thread.
     inferior.reset(new POSIXThread(*processSP, pid));
+    if (log)
+        log->Printf ("ProcessMonitor::%s() adding pid = %" PRIu64, __FUNCTION__, pid);
     process.GetThreadList().AddThread(inferior);
 
     // Let our process instance know the thread has stopped.
@@ -1016,12 +1030,6 @@ ProcessMonitor::StartAttachOpThread(Atta
         Host::ThreadCreate(g_thread_name, AttachOpThread, args, &error);
 }
 
-void
-ProcessMonitor::StopAttachOpThread()
-{
-    assert(!"Not implemented yet!!!");
-}
-
 void *
 ProcessMonitor::AttachOpThread(void *arg)
 {
@@ -1087,10 +1095,22 @@ ProcessMonitor::MonitorCallback(void *ca
     ProcessMessage message;
     ProcessMonitor *monitor = static_cast<ProcessMonitor*>(callback_baton);
     ProcessFreeBSD *process = monitor->m_process;
+    assert(process);
     bool stop_monitoring;
     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))
         stop_monitoring = true; // pid is gone.  Bail.
     else {
@@ -1118,6 +1138,8 @@ ProcessMonitor::MonitorSIGTRAP(ProcessMo
 {
     ProcessMessage message;
 
+    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
+
     assert(monitor);
     assert(info && info->si_signo == SIGTRAP && "Unexpected child signal!");
 
@@ -1135,17 +1157,23 @@ ProcessMonitor::MonitorSIGTRAP(ProcessMo
         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;
     }
@@ -1160,6 +1188,8 @@ ProcessMonitor::MonitorSignal(ProcessMon
     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 FreeBSD.
@@ -1170,12 +1200,21 @@ ProcessMonitor::MonitorSignal(ProcessMon
     // Similarly, ACK signals generated by this monitor.
     if (info->si_code == SI_USER)
     {
+        if (log)
+            log->Printf ("ProcessMonitor::%s() received signal %s with code %s, pid = %d",
+                            __FUNCTION__,
+                            monitor->m_process->GetUnixSignals().GetSignalAsCString (signo),
+                            "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);
@@ -1384,7 +1423,8 @@ ProcessMonitor::ServeOperation(Operation
                 assert(errno == EINTR);
                 goto READ_AGAIN;
             }
-
+            if (status == 0)
+                continue; // Poll again. The connection probably terminated.
             assert(status == sizeof(op));
             op->Execute(monitor);
             write(fdset.fd, &op, sizeof(op));
@@ -1509,8 +1549,15 @@ bool
 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;
 }
 
@@ -1550,14 +1597,16 @@ ProcessMonitor::GetEventMessage(lldb::ti
     return result;
 }
 
-Error
+lldb_private::Error
 ProcessMonitor::Detach(lldb::tid_t tid)
 {
-    Error result;
-    DetachOperation op(result);
-    DoOperation(&op);
-    StopMonitor();
-    return result;
+    lldb_private::Error error;
+    if (tid != LLDB_INVALID_THREAD_ID)
+    {
+        DetachOperation op(error);
+        DoOperation(&op);
+    }
+    return error;
 }    
 
 bool
@@ -1588,13 +1637,26 @@ void
 ProcessMonitor::StopMonitor()
 {
     StopMonitoringChildProcess();
-    StopLaunchOpThread();
+    StopOpThread();
     CloseFD(m_terminal_fd);
     CloseFD(m_client_fd);
     CloseFD(m_server_fd);
 }
 
 void
+ProcessMonitor::StopOpThread()
+{
+    lldb::thread_result_t result;
+
+    if (!IS_VALID_LLDB_HOST_THREAD(m_operation_thread))
+        return;
+
+    Host::ThreadCancel(m_operation_thread, NULL);
+    Host::ThreadJoin(m_operation_thread, &result, NULL);
+    m_operation_thread = LLDB_INVALID_HOST_THREAD;
+}
+
+void
 ProcessMonitor::CloseFD(int &fd)
 {
     if (fd != -1)

Modified: lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.h?rev=185442&r1=185441&r2=185442&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.h (original)
+++ lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.h Tue Jul  2 11:45:16 2013
@@ -244,9 +244,6 @@ private:
     void
     StartLaunchOpThread(LaunchArgs *args, lldb_private::Error &error);
 
-    void
-    StopLaunchOpThread();
-
     static void *
     LaunchOpThread(void *arg);
 
@@ -269,9 +266,6 @@ private:
     void
     StartAttachOpThread(AttachArgs *args, lldb_private::Error &error);
 
-    void
-    StopAttachOpThread();
-
     static void *
     AttachOpThread(void *args);
 
@@ -318,6 +312,10 @@ private:
     void 
     StopMonitor();
 
+    /// Stops the operation thread used to attach/launch a process.
+    void
+    StopOpThread();
+
     void
     CloseFD(int &fd);
 };





More information about the lldb-commits mailing list