[Lldb-commits] [lldb] r199959 - Added reaper for commandline-launched processes.

Todd Fiala tfiala at google.com
Thu Jan 23 16:52:53 PST 2014


Author: tfiala
Date: Thu Jan 23 18:52:53 2014
New Revision: 199959

URL: http://llvm.org/viewvc/llvm-project?rev=199959&view=rev
Log:
Added reaper for commandline-launched processes.

GDBRemoteCommunicationServer::LaunchProcess () now uses the built-up
ProcessLaunchArgs rather than clearing and setting items from the
function arguments. I added setters for the arguments and launch
flags, which lldb-gdbserver uses for its specification of the
commandline-specified startup app (if one is specified).

LaunchProcess () also adds a new reaper monitor that it applies to
the launched process if no process monitor has already been applied.

This addresses an issue where the 'k' command would generate (possibly
false) warnings about not being able to positively state whether a
killed process actually terminated. GDBRemoteCommunicationServer now
definitely knows the disposition of its children.

Modified:
    lldb/trunk/include/lldb/Target/Process.h
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
    lldb/trunk/tools/lldb-gdbserver/lldb-gdbserver.cpp

Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=199959&r1=199958&r2=199959&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Thu Jan 23 18:52:53 2014
@@ -800,6 +800,18 @@ public:
         m_monitor_signals = monitor_signals;
     }
 
+    Host::MonitorChildProcessCallback
+    GetMonitorProcessCallback ()
+    {
+        return m_monitor_callback;
+    }
+
+    const void*
+    GetMonitorProcessBaton () const
+    {
+        return m_monitor_callback_baton;
+    }
+
     bool
     MonitorProcess () const
     {

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp?rev=199959&r1=199958&r2=199959&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp Thu Jan 23 18:52:53 2014
@@ -276,24 +276,42 @@ GDBRemoteCommunicationServer::GetPacketA
 }
 
 lldb_private::Error
-GDBRemoteCommunicationServer::LaunchProcess (const char *const args[], int argc, unsigned int launch_flags)
+GDBRemoteCommunicationServer::SetLaunchArguments (const char *const args[], int argc)
 {
     if ((argc < 1) || !args || !args[0] || !args[0][0])
-        lldb_private::Error ("%s: no process command line specified to launch", __FUNCTION__);
+        return lldb_private::Error ("%s: no process command line specified to launch", __FUNCTION__);
 
-    // Launch the program specified in args
-    m_process_launch_info.Clear ();
     m_process_launch_info.SetArguments (const_cast<const char**> (args), true);
+    return lldb_private::Error ();
+}
+
+lldb_private::Error
+GDBRemoteCommunicationServer::SetLaunchFlags (unsigned int launch_flags)
+{
     m_process_launch_info.GetFlags ().Set (launch_flags);
+    return lldb_private::Error ();
+}
+
+lldb_private::Error
+GDBRemoteCommunicationServer::LaunchProcess ()
+{
+    if (!m_process_launch_info.GetArguments ().GetArgumentCount ())
+        return lldb_private::Error ("%s: no process command line specified to launch", __FUNCTION__);
+
+    // specify the process monitor if not already set.  This should
+    // generally be what happens since we need to reap started
+    // processes.
+    if (!m_process_launch_info.GetMonitorProcessCallback ())
+        m_process_launch_info.SetMonitorProcessCallback(ReapDebuggedProcess, this, false);
 
     lldb_private::Error error = Host::LaunchProcess (m_process_launch_info);
     if (!error.Success ())
     {
-        fprintf (stderr, "%s: failed to launch executable %s", __FUNCTION__, args[0]);
+        fprintf (stderr, "%s: failed to launch executable %s", __FUNCTION__, m_process_launch_info.GetArguments ().GetArgumentAtIndex (0));
         return error;
     }
 
-    printf ("Launched '%s' as process %" PRIu64 "...\n", args[0], m_process_launch_info.GetProcessID());
+    printf ("Launched '%s' as process %" PRIu64 "...\n", m_process_launch_info.GetArguments ().GetArgumentAtIndex (0), m_process_launch_info.GetProcessID());
 
     // add to list of spawned processes.  On an lldb-gdbserver, we
     // would expect there to be only one.
@@ -846,6 +864,26 @@ GDBRemoteCommunicationServer::ReapDebugs
     return true;
 }
 
+bool
+GDBRemoteCommunicationServer::DebuggedProcessReaped (lldb::pid_t pid)
+{
+    // reap a process that we were debugging (but not debugserver)
+    Mutex::Locker locker (m_spawned_pids_mutex);
+    return m_spawned_pids.erase(pid) > 0;
+}
+
+bool
+GDBRemoteCommunicationServer::ReapDebuggedProcess (void *callback_baton,
+                                                   lldb::pid_t pid,
+                                                   bool exited,
+                                                   int signal,    // Zero for no signal
+                                                   int status)    // Exit value of process if signal is zero
+{
+    GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer *)callback_baton;
+    server->DebuggedProcessReaped (pid);
+    return true;
+}
+
 GDBRemoteCommunication::PacketResult
 GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet)
 {

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h?rev=199959&r1=199958&r2=199959&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h Thu Jan 23 18:52:53 2014
@@ -139,11 +139,9 @@ public:
     }
 
     //------------------------------------------------------------------
-    /// Launch a process.
+    /// Specify the program to launch and its arguments.
     ///
-    /// This method supports running an lldb-gdbserver or similar
-    /// server in a situation where the startup code has been provided
-    /// with all the information for a child process to be launched.
+    /// The LaunchProcess () command can be executed to do the lauching.
     ///
     /// @param[in] args
     ///     The command line to launch.
@@ -151,15 +149,41 @@ public:
     /// @param[in] argc
     ///     The number of elements in the args array of cstring pointers.
     ///
+    /// @return
+    ///     An Error object indicating the success or failure of making
+    ///     the setting.
+    //------------------------------------------------------------------
+    lldb_private::Error
+    SetLaunchArguments (const char *const args[], int argc);
+
+    //------------------------------------------------------------------
+    /// Specify the launch flags for the process.
+    ///
+    /// The LaunchProcess () command can be executed to do the lauching.
+    ///
     /// @param[in] launch_flags
     ///     The launch flags to use when launching this process.
     ///
     /// @return
+    ///     An Error object indicating the success or failure of making
+    ///     the setting.
+    //------------------------------------------------------------------
+    lldb_private::Error
+    SetLaunchFlags (unsigned int launch_flags);
+
+    //------------------------------------------------------------------
+    /// Launch a process with the current launch settings.
+    ///
+    /// This method supports running an lldb-gdbserver or similar
+    /// server in a situation where the startup code has been provided
+    /// with all the information for a child process to be launched.
+    ///
+    /// @return
     ///     An Error object indicating the success or failure of the
     ///     launch.
     //------------------------------------------------------------------
     lldb_private::Error
-    LaunchProcess (const char *const args[], int argc, unsigned int launch_flags);
+    LaunchProcess ();
 
 protected:
     lldb::thread_t m_async_thread;
@@ -302,6 +326,16 @@ private:
                             int status);
 
     bool
+    DebuggedProcessReaped (lldb::pid_t pid);
+
+    static bool
+    ReapDebuggedProcess (void *callback_baton,
+                         lldb::pid_t pid,
+                         bool exited,
+                         int signal,
+                         int status);
+
+    bool
     KillSpawnedProcess (lldb::pid_t pid);
 
     //------------------------------------------------------------------

Modified: lldb/trunk/tools/lldb-gdbserver/lldb-gdbserver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-gdbserver/lldb-gdbserver.cpp?rev=199959&r1=199958&r2=199959&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-gdbserver/lldb-gdbserver.cpp (original)
+++ lldb/trunk/tools/lldb-gdbserver/lldb-gdbserver.cpp Thu Jan 23 18:52:53 2014
@@ -221,12 +221,26 @@ main (int argc, char *argv[])
     // to launch a program, or a vAttach packet to attach to an existing process.
     if (argc > 0)
     {
+        error = gdb_server.SetLaunchArguments (argv, argc);
+        if (error.Fail ())
+        {
+            fprintf (stderr, "error: failed to set launch args for '%s': %s\n", argv[0], error.AsCString());
+            exit(1);
+        }
+
         unsigned int launch_flags = eLaunchFlagStopAtEntry;
 #if !defined(__linux__)
         // linux doesn't yet handle eLaunchFlagDebug
         launch_flags |= eLaunchFlagDebug;
 #endif
-        error = gdb_server.LaunchProcess (argv, argc, launch_flags);
+        error = gdb_server.SetLaunchFlags (launch_flags);
+        if (error.Fail ())
+        {
+            fprintf (stderr, "error: failed to set launch flags for '%s': %s\n", argv[0], error.AsCString());
+            exit(1);
+        }
+
+        error = gdb_server.LaunchProcess ();
         if (error.Fail ())
         {
             fprintf (stderr, "error: failed to launch '%s': %s\n", argv[0], error.AsCString());





More information about the lldb-commits mailing list