[Lldb-commits] [lldb] r144780 - in /lldb/trunk: include/lldb/Core/Debugger.h include/lldb/Host/Host.h include/lldb/Target/Process.h source/Core/Debugger.cpp source/Host/common/Host.cpp source/Host/macosx/Host.mm source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp source/Plugins/Process/gdb-remote/ProcessGDBRemote.h source/Target/Process.cpp

Greg Clayton gclayton at apple.com
Tue Nov 15 21:37:57 PST 2011


Author: gclayton
Date: Tue Nov 15 23:37:56 2011
New Revision: 144780

URL: http://llvm.org/viewvc/llvm-project?rev=144780&view=rev
Log:
Made the darwin host layer properly reap any child processes that it spawns.
After recent changes we weren't reaping child processes resulting in many
zombie processes. 

This was fixed by adding more settings to the ProcessLaunchOptions class
that allow clients to specify a callback function and baton to be notified
when their process dies. If one is not supplied a default callback will be
used that "does the right thing". 

Cleaned up a race condition in the ProcessGDBRemote class that would attempt
to monitor when debugserver died. 

Added an extra boolean to the process monitor callbacks that indicate if a
process exited or not. If your process exited with a zero exit status and no
signal, both items could be zero.

Modified the process monitor functions to not require a callback function
in order to reap the child process.


Modified:
    lldb/trunk/include/lldb/Core/Debugger.h
    lldb/trunk/include/lldb/Host/Host.h
    lldb/trunk/include/lldb/Target/Process.h
    lldb/trunk/source/Core/Debugger.cpp
    lldb/trunk/source/Host/common/Host.cpp
    lldb/trunk/source/Host/macosx/Host.mm
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
    lldb/trunk/source/Target/Process.cpp

Modified: lldb/trunk/include/lldb/Core/Debugger.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Debugger.h?rev=144780&r1=144779&r2=144780&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Debugger.h (original)
+++ lldb/trunk/include/lldb/Core/Debugger.h Tue Nov 15 23:37:56 2011
@@ -260,6 +260,9 @@
 
     static lldb::TargetSP
     FindTargetWithProcessID (lldb::pid_t pid);
+    
+    static lldb::TargetSP
+    FindTargetWithProcess (Process *process);
 
     static void
     Initialize ();

Modified: lldb/trunk/include/lldb/Host/Host.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/Host.h?rev=144780&r1=144779&r2=144780&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/Host.h (original)
+++ lldb/trunk/include/lldb/Host/Host.h Tue Nov 15 23:37:56 2011
@@ -29,6 +29,7 @@
 public:
     typedef bool (*MonitorChildProcessCallback) (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
 

Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=144780&r1=144779&r2=144780&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Tue Nov 15 23:37:56 2011
@@ -35,6 +35,7 @@
 #include "lldb/Expression/ClangPersistentVariables.h"
 #include "lldb/Expression/IRDynamicChecks.h"
 #include "lldb/Host/FileSpec.h"
+#include "lldb/Host/Host.h"
 #include "lldb/Interpreter/Args.h"
 #include "lldb/Interpreter/Options.h"
 #include "lldb/Target/ExecutionContextScope.h"
@@ -399,7 +400,7 @@
     uint32_t m_egid;    
     lldb::pid_t m_parent_pid;
 };
-    
+
     
 //----------------------------------------------------------------------
 // ProcessLaunchInfo
@@ -500,7 +501,15 @@
                        const char *working_directory,
                        uint32_t launch_flags) :
         ProcessInfo(),
-        m_flags (launch_flags)
+        m_working_dir (),
+        m_plugin_name (),
+        m_shell (),
+        m_flags (launch_flags),
+        m_file_actions (), 
+        m_resume_count (0),
+        m_monitor_callback (NULL),
+        m_monitor_callback_baton (NULL),
+        m_monitor_signals (false)
     {
         if (stderr_path)
         {
@@ -715,6 +724,31 @@
     bool
     ConvertArgumentsForLaunchingInShell (Error &error, bool localhost);
     
+    void
+    SetMonitorProcessCallback (Host::MonitorChildProcessCallback callback, 
+                               void *baton, 
+                               bool monitor_signals)
+    {
+        m_monitor_callback = callback;
+        m_monitor_callback_baton = baton;
+        m_monitor_signals = monitor_signals;
+    }
+
+    bool
+    MonitorProcess () const
+    {
+        if (m_monitor_callback && ProcessIDIsValid())
+        {
+            Host::StartMonitoringChildProcess (m_monitor_callback,
+                                               m_monitor_callback_baton,
+                                               GetProcessID(), 
+                                               m_monitor_signals);
+            return true;
+        }
+        return false;
+    }
+    
+
 protected:
     std::string m_working_dir;
     std::string m_plugin_name;
@@ -722,6 +756,9 @@
     Flags m_flags;       // Bitwise OR of bits from lldb::LaunchFlags
     std::vector<FileAction> m_file_actions; // File actions for any other files
     uint32_t m_resume_count; // How many times do we resume after launching
+    Host::MonitorChildProcessCallback m_monitor_callback;
+    void *m_monitor_callback_baton;
+    bool m_monitor_signals;
 };
 
 //----------------------------------------------------------------------
@@ -1360,6 +1397,7 @@
     static bool
     SetProcessExitStatus (void *callback_baton,   // The callback baton which should be set to NULL
                           lldb::pid_t pid,        // The process ID we want to monitor
+                          bool exited,
                           int signo,              // Zero for no signal
                           int status);            // Exit value of process if signal is zero
 

Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=144780&r1=144779&r2=144780&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Tue Nov 15 23:37:56 2011
@@ -216,6 +216,22 @@
     return target_sp;
 }
 
+TargetSP
+Debugger::FindTargetWithProcess (Process *process)
+{
+    TargetSP target_sp;
+    Mutex::Locker locker (GetDebuggerListMutex ());
+    DebuggerList &debugger_list = GetDebuggerList();
+    DebuggerList::iterator pos, end = debugger_list.end();
+    for (pos = debugger_list.begin(); pos != end; ++pos)
+    {
+        target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
+        if (target_sp)
+            break;
+    }
+    return target_sp;
+}
+
 
 Debugger::Debugger () :
     UserID (g_unique_id++),

Modified: lldb/trunk/source/Host/common/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Host.cpp?rev=144780&r1=144779&r2=144780&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/Host.cpp (original)
+++ lldb/trunk/source/Host/common/Host.cpp Tue Nov 15 23:37:56 2011
@@ -56,6 +56,8 @@
 using namespace lldb;
 using namespace lldb_private;
 
+
+#if 1 // !defined (__APPLE__)
 struct MonitorInfo
 {
     lldb::pid_t pid;                            // The process ID to monitor
@@ -77,25 +79,20 @@
 )
 {
     lldb::thread_t thread = LLDB_INVALID_HOST_THREAD;
-    if (callback)
-    {
-        std::auto_ptr<MonitorInfo> info_ap(new MonitorInfo);
-            
-        info_ap->pid = pid;
-        info_ap->callback = callback;
-        info_ap->callback_baton = callback_baton;
-        info_ap->monitor_signals = monitor_signals;
+    MonitorInfo * info_ptr = new MonitorInfo();
         
-        char thread_name[256];
-        ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%i)>", pid);
-        thread = ThreadCreate (thread_name,
-                               MonitorChildProcessThreadFunction,
-                               info_ap.get(),
-                               NULL);
-                               
-        if (IS_VALID_LLDB_HOST_THREAD(thread))
-            info_ap.release();
-    }
+    info_ptr->pid = pid;
+    info_ptr->callback = callback;
+    info_ptr->callback_baton = callback_baton;
+    info_ptr->monitor_signals = monitor_signals;
+    
+    char thread_name[256];
+    ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%i)>", pid);
+    thread = ThreadCreate (thread_name,
+                           MonitorChildProcessThreadFunction,
+                           info_ptr,
+                           NULL);
+                           
     return thread;
 }
 
@@ -146,16 +143,15 @@
 
     int status = -1;
     const int options = 0;
-    struct rusage *rusage = NULL;
     while (1)
     {
         log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
         if (log)
-            log->Printf("%s ::wait4 (pid = %i, &status, options = %i, rusage = %p)...", function, pid, options, rusage);
+            log->Printf("%s ::wait_pid (pid = %i, &status, options = %i)...", function, pid, options);
 
         // Wait for all child processes
         ::pthread_testcancel ();
-        const lldb::pid_t wait_pid = ::wait4 (pid, &status, options, rusage);
+        const lldb::pid_t wait_pid = ::waitpid (pid, &status, options);
         ::pthread_testcancel ();
 
         if (wait_pid == -1)
@@ -200,11 +196,10 @@
 
                 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
                 if (log)
-                    log->Printf ("%s ::wait4 (pid = %i, &status, options = %i, rusage = %p) => pid = %i, status = 0x%8.8x (%s), signal = %i, exit_state = %i",
+                    log->Printf ("%s ::waitpid (pid = %i, &status, options = %i) => pid = %i, status = 0x%8.8x (%s), signal = %i, exit_state = %i",
                                  function,
                                  wait_pid,
                                  options,
-                                 rusage,
                                  pid,
                                  status,
                                  status_cstr,
@@ -213,7 +208,9 @@
 
                 if (exited || (signal != 0 && monitor_signals))
                 {
-                    bool callback_return = callback (callback_baton, pid, signal, exit_status);
+                    bool callback_return = false;
+                    if (callback)
+                        callback_return = callback (callback_baton, pid, exited, signal, exit_status);
                     
                     // If our process exited, then this thread should exit
                     if (exited)
@@ -234,6 +231,8 @@
     return NULL;
 }
 
+#endif // #if !defined (__APPLE__)
+
 size_t
 Host::GetPageSize()
 {

Modified: lldb/trunk/source/Host/macosx/Host.mm
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Host.mm?rev=144780&r1=144779&r2=144780&view=diff
==============================================================================
--- lldb/trunk/source/Host/macosx/Host.mm (original)
+++ lldb/trunk/source/Host/macosx/Host.mm Tue Nov 15 23:37:56 2011
@@ -1191,7 +1191,6 @@
     return false;
 }
 
-
 Error
 Host::LaunchProcess (ProcessLaunchInfo &launch_info)
 {
@@ -1396,7 +1395,17 @@
     if (pid != LLDB_INVALID_PROCESS_ID)
     {
         // If all went well, then set the process ID into the launch info
-        launch_info.SetProcessID(pid);        
+        launch_info.SetProcessID(pid);
+        
+        // Make sure we reap any processes we spawn or we will have zombies.
+        if (!launch_info.MonitorProcess())
+        {
+            const bool monitor_signals = false;
+            StartMonitoringChildProcess (Process::SetProcessExitStatus, 
+                                         NULL, 
+                                         pid, 
+                                         monitor_signals);
+        }
     }
     else
     {
@@ -1407,4 +1416,104 @@
     return error;
 }
 
+#if 0
 
+lldb::thread_t
+Host::StartMonitoringChildProcess (Host::MonitorChildProcessCallback callback,
+                                   void *callback_baton,
+                                   lldb::pid_t pid,
+                                   bool monitor_signals)
+{
+    lldb::thread_t thread = LLDB_INVALID_HOST_THREAD;
+    unsigned long mask = DISPATCH_PROC_EXIT;
+    if (monitor_signals)
+        mask |= DISPATCH_PROC_SIGNAL;
+
+
+    dispatch_source_t source = ::dispatch_source_create (DISPATCH_SOURCE_TYPE_PROC, 
+                                                         pid, 
+                                                         mask, 
+                                                         ::dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT,0));
+
+    printf ("Host::StartMonitoringChildProcess (callback=%p, baton=%p, pid=%i, monitor_signals=%i) source = %p\n", 
+            callback, 
+            callback_baton, 
+            (int)pid, 
+            monitor_signals, 
+            source);
+
+    if (source)
+    {
+        ::dispatch_source_set_cancel_handler (source, ^{
+            printf ("::dispatch_source_set_cancel_handler (source=%p, ^{...\n", source);
+            ::dispatch_release (source);
+        });
+        ::dispatch_source_set_event_handler (source, ^{
+            
+            printf ("::dispatch_source_set_event_handler (source=%p, ^{...\n", source);
+
+            int status= 0;
+            int wait_pid = 0;
+            bool cancel = false;
+            bool exited = false;
+            do
+            {
+                wait_pid = ::waitpid (pid, &status, 0);
+            } while (wait_pid < 0 && errno == EINTR);
+
+            if (wait_pid >= 0)
+            {
+                int signal = 0;
+                int exit_status = 0;
+                const char *status_cstr = NULL;
+                if (WIFSTOPPED(status))
+                {
+                    signal = WSTOPSIG(status);
+                    status_cstr = "STOPPED";
+                }
+                else if (WIFEXITED(status))
+                {
+                    exit_status = WEXITSTATUS(status);
+                    status_cstr = "EXITED";
+                    exited = true;
+                }
+                else if (WIFSIGNALED(status))
+                {
+                    signal = WTERMSIG(status);
+                    status_cstr = "SIGNALED";
+                    exited = true;
+                    exit_status = -1;
+                }
+                else
+                {
+                    status_cstr = "???";
+                }
+
+                LogSP log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+                if (log)
+                    log->Printf ("::waitpid (pid = %i, &status, 0) => pid = %i, status = 0x%8.8x (%s), signal = %i, exit_status = %i",
+                                 pid,
+                                 wait_pid,
+                                 status,
+                                 status_cstr,
+                                 signal,
+                                 exit_status);
+                
+                if (callback)
+                    cancel = callback (callback_baton, pid, exited, signal, exit_status);
+                
+                if (exited)
+                {
+                    printf ("::dispatch_source_set_event_handler (source=%p, ^{...  dispatch_source_cancel(source);\n", source);
+                    ::dispatch_source_cancel(source);
+                }
+            }
+        });
+
+        ::dispatch_resume (source);
+    }
+    return thread;
+}
+
+
+#endif

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=144780&r1=144779&r2=144780&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Tue Nov 15 23:37:56 2011
@@ -122,7 +122,6 @@
     m_flags (0),
     m_gdb_comm(false),
     m_debugserver_pid (LLDB_INVALID_PROCESS_ID),
-    m_debugserver_thread (LLDB_INVALID_HOST_THREAD),
     m_last_stop_packet (),
     m_register_info (),
     m_async_broadcaster ("lldb.process.gdb-remote.async-broadcaster"),
@@ -145,13 +144,6 @@
 //----------------------------------------------------------------------
 ProcessGDBRemote::~ProcessGDBRemote()
 {
-    if (IS_VALID_LLDB_HOST_THREAD(m_debugserver_thread))
-    {
-        Host::ThreadCancel (m_debugserver_thread, NULL);
-        thread_result_t thread_result;
-        Host::ThreadJoin (m_debugserver_thread, &thread_result, NULL);
-        m_debugserver_thread = LLDB_INVALID_HOST_THREAD;
-    }
     //  m_mach_process.UnregisterNotificationCallbacks (this);
     Clear();
     // We need to call finalize on the process before destroying ourselves
@@ -669,11 +661,6 @@
             error.SetErrorString("not connected to remote gdb server");
         return error;
     }
-    if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
-        m_debugserver_thread = Host::StartMonitoringChildProcess (MonitorDebugserverProcess,
-                                                                  this,
-                                                                  m_debugserver_pid,
-                                                                  false);
     m_gdb_comm.ResetDiscoverableSettings();
     m_gdb_comm.QueryNoAckModeSupported ();
     m_gdb_comm.GetThreadSuffixSupported ();
@@ -2122,6 +2109,8 @@
                 log->Printf("%s arguments:\n%s", debugserver_args.GetArgumentAtIndex(0), strm.GetData());
             }
 
+            launch_info.SetMonitorProcessCallback (MonitorDebugserverProcess, this, false);
+
             error = Host::LaunchProcess(launch_info);
 
             if (error.Success ())
@@ -2148,61 +2137,85 @@
 (
     void *callback_baton,
     lldb::pid_t debugserver_pid,
+    bool exited,        // True if the process did exit
     int signo,          // Zero for no signal
     int exit_status     // Exit value of process if signal is zero
 )
 {
-    // We pass in the ProcessGDBRemote inferior process it and name it
-    // "gdb_remote_pid". The process ID is passed in the "callback_baton"
-    // pointer value itself, thus we need the double cast...
+    // The baton is a "ProcessGDBRemote *". Now this class might be gone
+    // and might not exist anymore, so we need to carefully try to get the
+    // target for this process first since we have a race condition when
+    // we are done running between getting the notice that the inferior 
+    // process has died and the debugserver that was debugging this process.
+    // In our test suite, we are also continually running process after
+    // process, so we must be very careful to make sure:
+    // 1 - process object hasn't been deleted already
+    // 2 - that a new process object hasn't been recreated in its place
 
     // "debugserver_pid" argument passed in is the process ID for
     // debugserver that we are tracking...
+    LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
 
     ProcessGDBRemote *process = (ProcessGDBRemote *)callback_baton;
 
-    LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+    // Get a shared pointer to the target that has a matching process pointer.
+    // This target could be gone, or the target could already have a new process
+    // object inside of it
+    TargetSP target_sp (Debugger::FindTargetWithProcess(process));
+
     if (log)
         log->Printf ("ProcessGDBRemote::MonitorDebugserverProcess (baton=%p, pid=%i, signo=%i (0x%x), exit_status=%i)", callback_baton, debugserver_pid, signo, signo, exit_status);
 
-    if (process)
+    if (target_sp)
     {
-        // Sleep for a half a second to make sure our inferior process has
-        // time to set its exit status before we set it incorrectly when
-        // both the debugserver and the inferior process shut down.
-        usleep (500000);
-        // If our process hasn't yet exited, debugserver might have died.
-        // If the process did exit, the we are reaping it.
-        const StateType state = process->GetState();
-        
-        if (process->m_debugserver_pid != LLDB_INVALID_PROCESS_ID &&
-            state != eStateInvalid &&
-            state != eStateUnloaded &&
-            state != eStateExited &&
-            state != eStateDetached)
-        {
-            char error_str[1024];
-            if (signo)
-            {
-                const char *signal_cstr = process->GetUnixSignals().GetSignalAsCString (signo);
-                if (signal_cstr)
-                    ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %s", signal_cstr);
+        // We found a process in a target that matches, but another thread
+        // might be in the process of launching a new process that will
+        // soon replace it, so get a shared pointer to the process so we
+        // can keep it alive.
+        ProcessSP process_sp (target_sp->GetProcessSP());
+        // Now we have a shared pointer to the process that can't go away on us
+        // so we now make sure it was the same as the one passed in, and also make
+        // sure that our previous "process *" didn't get deleted and have a new 
+        // "process *" created in its place with the same pointer. To verify this
+        // we make sure the process has our debugserver process ID. If we pass all
+        // of these tests, then we are sure that this process is the one we were
+        // looking for.
+        if (process_sp && process == process_sp.get() && process->m_debugserver_pid == debugserver_pid)
+        {
+            // Sleep for a half a second to make sure our inferior process has
+            // time to set its exit status before we set it incorrectly when
+            // both the debugserver and the inferior process shut down.
+            usleep (500000);
+            // If our process hasn't yet exited, debugserver might have died.
+            // If the process did exit, the we are reaping it.
+            const StateType state = process->GetState();
+            
+            if (process->m_debugserver_pid != LLDB_INVALID_PROCESS_ID &&
+                state != eStateInvalid &&
+                state != eStateUnloaded &&
+                state != eStateExited &&
+                state != eStateDetached)
+            {
+                char error_str[1024];
+                if (signo)
+                {
+                    const char *signal_cstr = process->GetUnixSignals().GetSignalAsCString (signo);
+                    if (signal_cstr)
+                        ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %s", signal_cstr);
+                    else
+                        ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %i", signo);
+                }
                 else
-                    ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %i", signo);
-            }
-            else
-            {
-                ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with an exit status of 0x%8.8x", exit_status);
-            }
+                {
+                    ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with an exit status of 0x%8.8x", exit_status);
+                }
 
-            process->SetExitStatus (-1, error_str);
+                process->SetExitStatus (-1, error_str);
+            }
+            // Debugserver has exited we need to let our ProcessGDBRemote
+            // know that it no longer has a debugserver instance
+            process->m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
         }
-        // Debugserver has exited we need to let our ProcessGDBRemote
-        // know that it no longer has a debugserver instance
-        process->m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
-        // We are returning true to this function below, so we can
-        // forget about the monitor handle.
-        process->m_debugserver_thread = LLDB_INVALID_HOST_THREAD;
     }
     return true;
 }

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=144780&r1=144779&r2=144780&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Tue Nov 15 23:37:56 2011
@@ -279,7 +279,6 @@
     lldb_private::Flags m_flags;            // Process specific flags (see eFlags enums)
     GDBRemoteCommunicationClient m_gdb_comm;
     lldb::pid_t m_debugserver_pid;
-    lldb::thread_t m_debugserver_thread;
     StringExtractorGDBRemote m_last_stop_packet;
     GDBRemoteDynamicRegisterInfo m_register_info;
     lldb_private::Broadcaster m_async_broadcaster;
@@ -308,8 +307,9 @@
     static bool
     MonitorDebugserverProcess (void *callback_baton,
                                lldb::pid_t pid,
-                               int signo,           // Zero for no signal
-                               int exit_status);    // Exit value of process if signal is zero
+                               bool exited,
+                               int signo,
+                               int exit_status);
 
     lldb::StateType
     SetThreadStopInfo (StringExtractor& stop_packet);

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=144780&r1=144779&r2=144780&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Tue Nov 15 23:37:56 2011
@@ -1136,15 +1136,23 @@
 // found in the global target list (we want to be completely sure that the
 // lldb_private::Process doesn't go away before we can deliver the signal.
 bool
-Process::SetProcessExitStatus
-(
-    void *callback_baton,
-    lldb::pid_t pid,
-    int signo,      // Zero for no signal
-    int exit_status      // Exit value of process if signal is zero
+Process::SetProcessExitStatus (void *callback_baton,
+                               lldb::pid_t pid,
+                               bool exited,
+                               int signo,          // Zero for no signal
+                               int exit_status     // Exit value of process if signal is zero
 )
 {
-    if (signo == 0 || exit_status)
+    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS));
+    if (log)
+        log->Printf ("Process::SetProcessExitStatus (baton=%p, pid=%i, exited=%i, signal=%i, exit_status=%i)\n", 
+                     callback_baton,
+                     pid,
+                     exited,
+                     signo,
+                     exit_status);
+
+    if (exited)
     {
         TargetSP target_sp(Debugger::FindTargetWithProcessID (pid));
         if (target_sp)





More information about the lldb-commits mailing list