I reverted TestProcessAttach changes and merged with 
http://reviews.llvm.org/D7358 - no regressions noticed for local test runs on 
Ubuntu and OSX, remote Linux->Linux execution of TestProcessAttach works fine.
Please take another look.

Thank you!


http://reviews.llvm.org/D7263

Files:
  include/lldb/API/SBPlatform.h
  include/lldb/Target/Platform.h
  scripts/Python/interface/SBPlatform.i
  source/API/SBPlatform.cpp
  source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
  source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
  source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
  source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
  source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
  source/Target/Platform.cpp
  test/lldbtest.py

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: include/lldb/API/SBPlatform.h
===================================================================
--- include/lldb/API/SBPlatform.h
+++ include/lldb/API/SBPlatform.h
@@ -12,6 +12,9 @@
 
 #include "lldb/API/SBDefines.h"
 
+#include <functional>
+#include <string>
+
 struct PlatformConnectOptions;
 struct PlatformShellCommand;
 
@@ -100,6 +103,35 @@
         PlatformShellCommand *m_opaque_ptr;
     };
 
+    class SBPlatformLaunchCommand
+    {
+    public:
+        SBPlatformLaunchCommand (const char* command,
+                                 const char* working_dir,
+                                 const char* arch);
+
+        const char*
+        GetCommand () const;
+
+        const char*
+        GetWorkingDir () const;
+
+        const char*
+        GetArch () const;
+
+        const lldb::pid_t&
+        GetPID () const;
+
+        void
+        SetPID (const lldb::pid_t& pid);
+
+    private:
+        const std::string m_command;
+        const std::string m_working_dir;
+        const std::string m_arch;
+        lldb::pid_t m_pid;
+    };
+
     class SBPlatform
     {
     public:
@@ -171,6 +203,12 @@
         Run (SBPlatformShellCommand &shell_command);
 
         SBError
+        Launch (SBPlatformLaunchCommand &launch_command);
+
+        SBError
+        Kill (const lldb::pid_t pid);
+
+        SBError
         MakeDirectory (const char *path, uint32_t file_permissions = eFilePermissionsDirectoryDefault);
 
         uint32_t
@@ -190,6 +228,9 @@
         void
         SetSP (const lldb::PlatformSP& platform_sp);
 
+        SBError
+        ExecuteConnected (const std::function<lldb_private::Error(const lldb::PlatformSP&)>& func);
+
         lldb::PlatformSP m_opaque_sp;
     };
 
Index: include/lldb/Target/Platform.h
===================================================================
--- include/lldb/Target/Platform.h
+++ include/lldb/Target/Platform.h
@@ -380,6 +380,12 @@
         LaunchProcess (ProcessLaunchInfo &launch_info);
 
         //------------------------------------------------------------------
+        /// Kill process on a platform.
+        //------------------------------------------------------------------
+        virtual Error
+        KillProcess (const lldb::pid_t pid);
+
+        //------------------------------------------------------------------
         /// Lets a platform answer if it is compatible with a given
         /// architecture and the target triple contained within.
         //------------------------------------------------------------------
Index: scripts/Python/interface/SBPlatform.i
===================================================================
--- scripts/Python/interface/SBPlatform.i
+++ scripts/Python/interface/SBPlatform.i
@@ -83,6 +83,29 @@
     GetOutput ();
 };
 
+class SBPlatformLaunchCommand
+{
+public:
+    SBPlatformLaunchCommand (const char* command,
+                             const char* working_dir,
+                             const char* arch);
+
+    const char*
+    GetCommand () const;
+
+    const char*
+    GetWorkingDir () const;
+
+    const char*
+    GetArch () const;
+
+    const lldb::pid_t&
+    GetPID () const;
+
+    void
+    SetPID (const lldb::pid_t& pid);
+};
+
 %feature("docstring",
 "A class that represents the a platform that can represent the current host or a remote host debug platform.
 
@@ -174,6 +197,12 @@
     Run (lldb::SBPlatformShellCommand &shell_command);
 
     lldb::SBError
+    Launch (lldb::SBPlatformLaunchCommand &launch_command);
+
+    lldb::SBError
+    Kill (const lldb::pid_t pid);
+
+    lldb::SBError
     MakeDirectory (const char *path, uint32_t file_permissions = lldb::eFilePermissionsDirectoryDefault);
     
     uint32_t
Index: source/API/SBPlatform.cpp
===================================================================
--- source/API/SBPlatform.cpp
+++ source/API/SBPlatform.cpp
@@ -14,6 +14,7 @@
 #include "lldb/Core/Error.h"
 #include "lldb/Host/File.h"
 #include "lldb/Interpreter/Args.h"
+#include "lldb/Target/ProcessLaunchInfo.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Platform.h"
 
@@ -215,6 +216,7 @@
     return m_opaque_ptr->m_working_dir.c_str();
 }
 
+
 void
 SBPlatformShellCommand::SetWorkingDirectory (const char *path)
 {
@@ -257,6 +259,50 @@
 }
 
 //----------------------------------------------------------------------
+// SBPlatformLaunchCommand
+//----------------------------------------------------------------------
+
+SBPlatformLaunchCommand::SBPlatformLaunchCommand (const char* command,
+                                                  const char* working_dir,
+                                                  const char* arch) :
+    m_command (command ? command : ""),
+    m_working_dir (working_dir ? working_dir: ""),
+    m_arch (arch ? arch: ""),
+    m_pid(LLDB_INVALID_PROCESS_ID)
+{
+}
+
+const char*
+SBPlatformLaunchCommand::GetCommand () const
+{
+    return m_command.c_str ();
+}
+
+const char*
+SBPlatformLaunchCommand::GetWorkingDir () const
+{
+    return m_working_dir.c_str ();
+}
+
+const char*
+SBPlatformLaunchCommand::GetArch () const
+{
+    return m_arch.c_str ();
+}
+
+const lldb::pid_t&
+SBPlatformLaunchCommand::GetPID () const
+{
+    return m_pid;
+}
+
+void
+SBPlatformLaunchCommand::SetPID (const lldb::pid_t& pid)
+{
+    m_pid = pid;
+}
+
+//----------------------------------------------------------------------
 // SBPlatform
 //----------------------------------------------------------------------
 SBPlatform::SBPlatform () :
@@ -484,104 +530,129 @@
 SBPlatform::Put (SBFileSpec &src,
                  SBFileSpec &dst)
 {
-    SBError sb_error;
-    
-    PlatformSP platform_sp(GetSP());
-    if (platform_sp)
-    {
-        if (src.Exists())
+  return ExecuteConnected(
+      [&](const lldb::PlatformSP& platform_sp)
+      {
+          if (src.Exists())
+          {
+              uint32_t permissions = src.ref().GetPermissions();
+              if (permissions == 0)
+              {
+                  if (src.ref().GetFileType() == FileSpec::eFileTypeDirectory)
+                      permissions = eFilePermissionsDirectoryDefault;
+                  else
+                      permissions = eFilePermissionsFileDefault;
+              }
+
+              return platform_sp->PutFile(src.ref(), dst.ref(), permissions);
+          }
+
+          Error error;
+          error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str());
+          return error;
+      });
+}
+
+SBError
+SBPlatform::Install (SBFileSpec &src,
+                     SBFileSpec &dst)
+{
+  return ExecuteConnected(
+      [&](const lldb::PlatformSP& platform_sp)
+      {
+          if (src.Exists())
+              return platform_sp->Install(src.ref(), dst.ref());
+
+          Error error;
+          error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str());
+          return error;
+      });
+}
+
+
+SBError
+SBPlatform::Run (SBPlatformShellCommand &shell_command)
+{
+    return ExecuteConnected(
+        [&](const lldb::PlatformSP& platform_sp)
         {
-            uint32_t permissions = src.ref().GetPermissions();
-            if (permissions == 0)
+            const char *command = shell_command.GetCommand();
+            if (!command)
+                return Error("invalid shell command (empty)");
+
+            const char *working_dir = shell_command.GetWorkingDirectory();
+            if (working_dir == NULL)
             {
-                if (src.ref().GetFileType() == FileSpec::eFileTypeDirectory)
-                    permissions = eFilePermissionsDirectoryDefault;
-                else
-                    permissions = eFilePermissionsFileDefault;
+                working_dir = platform_sp->GetWorkingDirectory().GetCString();
+                if (working_dir)
+                    shell_command.SetWorkingDirectory(working_dir);
             }
+            return platform_sp->RunShellCommand(command,
+                                                working_dir,
+                                                &shell_command.m_opaque_ptr->m_status,
+                                                &shell_command.m_opaque_ptr->m_signo,
+                                                &shell_command.m_opaque_ptr->m_output,
+                                                shell_command.m_opaque_ptr->m_timeout_sec);
+        });
+}
 
-            sb_error.ref() = platform_sp->PutFile(src.ref(),
-                                                  dst.ref(),
-                                                  permissions);
-        }
-        else
+SBError
+SBPlatform::Launch (SBPlatformLaunchCommand &launch_command)
+{
+    return ExecuteConnected(
+        [&](const lldb::PlatformSP& platform_sp)
         {
-            sb_error.ref().SetErrorStringWithFormat("'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str());
-        }
-    }
-    else
-    {
-        sb_error.SetErrorString("invalid platform");
-    }
-    return sb_error;
+            auto command = launch_command.GetCommand();
+            if (!command)
+                return Error("invalid launch command (empty)");
+
+            ProcessLaunchInfo launch_info;
+            launch_info.SetArguments(Args(command), true);
+
+            auto working_dir = launch_command.GetWorkingDir();
+            if (working_dir == nullptr)
+                working_dir = platform_sp->GetWorkingDirectory().GetCString();
+            launch_info.SetWorkingDirectory(working_dir);
+            auto arch = launch_command.GetArch();
+            if (arch)
+                launch_info.SetArchitecture(ArchSpec(arch));
+            else
+                launch_info.SetArchitecture(platform_sp->GetRemoteSystemArchitecture());
+
+            auto error = platform_sp->LaunchProcess(launch_info);
+            if (error.Success())
+                launch_command.SetPID(launch_info.GetProcessID());
+
+            return error;
+        });
 }
 
 SBError
-SBPlatform::Install (SBFileSpec &src,
-                     SBFileSpec &dst)
+SBPlatform::Kill (const lldb::pid_t pid)
 {
-    SBError sb_error;
-    PlatformSP platform_sp(GetSP());
-    if (platform_sp)
-    {
-        if (src.Exists())
+    return ExecuteConnected(
+        [&](const lldb::PlatformSP& platform_sp)
         {
-            sb_error.ref() = platform_sp->Install(src.ref(), dst.ref());
-        }
-        else
-        {
-            sb_error.ref().SetErrorStringWithFormat("'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str());
-        }
-    }
-    else
-    {
-        sb_error.SetErrorString("invalid platform");
-    }
-    return sb_error;
+            return platform_sp->KillProcess(pid);
+        });
 }
 
-
 SBError
-SBPlatform::Run (SBPlatformShellCommand &shell_command)
+SBPlatform::ExecuteConnected (const std::function<Error(const lldb::PlatformSP&)>& func)
 {
     SBError sb_error;
-    PlatformSP platform_sp(GetSP());
+    const auto platform_sp(GetSP());
     if (platform_sp)
     {
         if (platform_sp->IsConnected())
-        {
-            const char *command = shell_command.GetCommand();
-            if (command)
-            {
-                const char *working_dir = shell_command.GetWorkingDirectory();
-                if (working_dir == NULL)
-                {
-                    working_dir = platform_sp->GetWorkingDirectory().GetCString();
-                    if (working_dir)
-                        shell_command.SetWorkingDirectory(working_dir);
-                }
-                sb_error.ref() = platform_sp->RunShellCommand(command,
-                                                              working_dir,
-                                                              &shell_command.m_opaque_ptr->m_status,
-                                                              &shell_command.m_opaque_ptr->m_signo,
-                                                              &shell_command.m_opaque_ptr->m_output,
-                                                              shell_command.m_opaque_ptr->m_timeout_sec);
-            }
-            else
-            {
-                sb_error.SetErrorString("invalid shell command (empty)");
-            }
-        }
+            sb_error.ref() = func(platform_sp);
         else
-        {
             sb_error.SetErrorString("not connected");
-        }
     }
     else
-    {
         sb_error.SetErrorString("invalid platform");
-    }
-    return sb_error;
+
+  return sb_error;
 }
 
 SBError
Index: source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
===================================================================
--- source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -430,7 +430,6 @@
 {
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
     Error error;
-    lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
 
     if (log)
         log->Printf ("PlatformRemoteGDBServer::%s() called", __FUNCTION__);
@@ -475,7 +474,7 @@
         std::string error_str;
         if (m_gdb_client.GetLaunchSuccess (error_str))
         {
-            pid = m_gdb_client.GetCurrentProcessID ();
+            const auto pid = m_gdb_client.GetCurrentProcessID (false);
             if (pid != LLDB_INVALID_PROCESS_ID)
             {
                 launch_info.SetProcessID (pid);
@@ -486,7 +485,7 @@
             {
                 if (log)
                     log->Printf ("PlatformRemoteGDBServer::%s() launch succeeded but we didn't get a valid process id back!", __FUNCTION__);
-                // FIXME isn't this an error condition? Do we need to set an error here?  Check with Greg.
+                error.SetErrorString ("failed to get PID");
             }
         }
         else
@@ -503,6 +502,14 @@
     return error;
 }
 
+Error
+PlatformRemoteGDBServer::KillProcess (const lldb::pid_t pid)
+{
+    if (!m_gdb_client.KillSpawnedProcess(pid))
+        return Error("failed to kill remote spawned process");
+    return Error();
+}
+
 lldb::ProcessSP
 PlatformRemoteGDBServer::DebugProcess (lldb_private::ProcessLaunchInfo &launch_info,
                                        lldb_private::Debugger &debugger,
Index: source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
===================================================================
--- source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
+++ source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
@@ -86,7 +86,10 @@
 
     virtual lldb_private::Error
     LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info);
-    
+
+    virtual lldb_private::Error
+    KillProcess (const lldb::pid_t pid);
+
     virtual lldb::ProcessSP
     DebugProcess (lldb_private::ProcessLaunchInfo &launch_info,
                   lldb_private::Debugger &debugger,
Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
===================================================================
--- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -1211,13 +1211,13 @@
 }
 
 lldb::pid_t
-GDBRemoteCommunicationClient::GetCurrentProcessID ()
+GDBRemoteCommunicationClient::GetCurrentProcessID (bool allow_lazy)
 {
-    if (m_curr_pid_is_valid == eLazyBoolYes)
+    if (allow_lazy && m_curr_pid_is_valid == eLazyBoolYes)
         return m_curr_pid;
     
     // First try to retrieve the pid via the qProcessInfo request.
-    GetCurrentProcessInfo ();
+    GetCurrentProcessInfo (allow_lazy);
     if (m_curr_pid_is_valid == eLazyBoolYes)
     {
         // We really got it.
@@ -2409,14 +2409,17 @@
 }
 
 bool
-GDBRemoteCommunicationClient::GetCurrentProcessInfo ()
+GDBRemoteCommunicationClient::GetCurrentProcessInfo (bool allow_lazy)
 {
     Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
 
-    if (m_qProcessInfo_is_valid == eLazyBoolYes)
-        return true;
-    if (m_qProcessInfo_is_valid == eLazyBoolNo)
-        return false;
+    if (allow_lazy)
+    {
+        if (m_qProcessInfo_is_valid == eLazyBoolYes)
+            return true;
+        if (m_qProcessInfo_is_valid == eLazyBoolNo)
+            return false;
+    }
 
     GetHostInfo ();
 
Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
===================================================================
--- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -109,7 +109,7 @@
                    bool &timed_out);
 
     lldb::pid_t
-    GetCurrentProcessID ();
+    GetCurrentProcessID (bool allow_lazy = true);
 
     bool
     GetLaunchSuccess (std::string &error_str);
@@ -534,7 +534,7 @@
                                         StringExtractorGDBRemote &response);
 
     bool
-    GetCurrentProcessInfo ();
+    GetCurrentProcessInfo (bool allow_lazy_pid = true);
 
     bool
     GetGDBServerVersion();
Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
===================================================================
--- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -603,14 +603,12 @@
 
     // add to list of spawned processes.  On an lldb-gdbserver, we
     // would expect there to be only one.
-    lldb::pid_t pid;
-    if ( (pid = m_process_launch_info.GetProcessID()) != LLDB_INVALID_PROCESS_ID )
+    const auto pid = m_process_launch_info.GetProcessID();
+    if (pid != LLDB_INVALID_PROCESS_ID)
     {
         // add to spawned pids
-        {
-            Mutex::Locker locker (m_spawned_pids_mutex);
-            m_spawned_pids.insert(pid);
-        }
+        Mutex::Locker locker (m_spawned_pids_mutex);
+        m_spawned_pids.insert(pid);
     }
 
     return error;
@@ -1424,23 +1422,33 @@
 GDBRemoteCommunication::PacketResult
 GDBRemoteCommunicationServer::Handle_qProcessInfo (StringExtractorGDBRemote &packet)
 {
-    // Only the gdb server handles this.
-    if (!IsGdbServer ())
-        return SendUnimplementedResponse (packet.GetStringRef ().c_str ());
-    
-    // Fail if we don't have a current process.
-    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
-        return SendErrorResponse (68);
-    
-    ProcessInstanceInfo proc_info;
-    if (Host::GetProcessInfo (m_debugged_process_sp->GetID (), proc_info))
+    lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+
+    if (IsGdbServer ())
     {
-        StreamString response;
-        CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
-        return SendPacketNoLock (response.GetData (), response.GetSize ());
+        // Fail if we don't have a current process.
+        if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
+            return SendErrorResponse (68);
+
+        pid = m_debugged_process_sp->GetID ();
     }
-    
-    return SendErrorResponse (1);
+    else if (m_is_platform)
+    {
+        pid = m_process_launch_info.GetProcessID ();
+    }
+    else
+        return SendUnimplementedResponse (packet.GetStringRef ().c_str ());
+
+    if (pid == LLDB_INVALID_PROCESS_ID)
+        return SendErrorResponse (1);
+
+    ProcessInstanceInfo proc_info;
+    if (!Host::GetProcessInfo (pid, proc_info))
+        return SendErrorResponse (1);
+
+    StreamString response;
+    CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
+    return SendPacketNoLock (response.GetData (), response.GetSize ());
 }
 
 GDBRemoteCommunication::PacketResult
Index: source/Target/Platform.cpp
===================================================================
--- source/Target/Platform.cpp
+++ source/Target/Platform.cpp
@@ -1103,6 +1103,20 @@
     return error;
 }
 
+Error
+Platform::KillProcess (const lldb::pid_t pid)
+{
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
+    if (log)
+        log->Printf ("Platform::%s, pid %" PRIu64, __FUNCTION__, pid);
+
+    if (!IsHost ())
+        return Error ("base lldb_private::Platform class can't launch remote processes");
+
+    Host::Kill (pid, SIGTERM);
+    return Error();
+}
+
 lldb::ProcessSP
 Platform::DebugProcess (ProcessLaunchInfo &launch_info, 
                         Debugger &debugger,
Index: test/lldbtest.py
===================================================================
--- test/lldbtest.py
+++ test/lldbtest.py
@@ -31,6 +31,7 @@
 $ 
 """
 
+import abc
 import os, sys, traceback
 import os.path
 import re
@@ -41,6 +42,7 @@
 import types
 import unittest2
 import lldb
+from _pyio import __metaclass__
 
 # See also dotest.parseOptionsAndInitTestdirs(), where the environment variables
 # LLDB_COMMAND_TRACE and LLDB_DO_CLEANUP are set from '-t' and '-r dir' options.
@@ -233,6 +235,72 @@
             print >> self.session, self.getvalue()
         self.close()
 
+class _BaseProcess(object):
+    __metaclass__ = abc.ABCMeta
+
+    @abc.abstractproperty
+    def pid(self):
+        """Returns process PID if has been launched already."""
+
+    @abc.abstractmethod
+    def launch(self, executable, args):
+        """Launches new process with given executable and args."""
+
+    @abc.abstractmethod
+    def terminate(self):
+        """Terminates previously launched process.."""
+
+class _LocalProcess(_BaseProcess):
+
+    def __init__(self, trace_on):
+        self._proc = None
+        self._trace_on = trace_on
+
+    @property
+    def pid(self):
+        return self._proc.pid
+
+    def launch(self, executable, args):
+        self._proc = Popen([executable] + args,
+                           stdout = open(os.devnull) if not self._trace_on else None,
+                           stdin = PIPE)
+
+    def terminate(self):
+        if self._proc.poll() == None:
+            self._proc.terminate()
+
+class _RemoteProcess(_BaseProcess):
+
+    def __init__(self):
+        self._pid = None
+
+    @property
+    def pid(self):
+        return self._pid
+
+    def launch(self, executable, args):
+        remote_work_dir = lldb.remote_platform.GetWorkingDirectory()
+        src_path = executable
+        dst_path = os.path.join(remote_work_dir, os.path.basename(executable))
+
+        err = lldb.remote_platform.Install(lldb.SBFileSpec(src_path, True),
+                                           lldb.SBFileSpec(dst_path, False))
+        if err.Fail():
+            raise Exception("remote_platform.Install('%s', '%s') failed: %s" % (src_path, dst_path, err))
+
+        cmd = lldb.SBPlatformLaunchCommand(' '.join([dst_path] + args),
+                                           remote_work_dir,
+                                           None)
+        err = lldb.remote_platform.Launch(cmd)
+        if err.Fail():
+            raise Exception("remote_platform.Launch('%s', '%s') failed: %s" % (dst_path, args, err))
+        self._pid = cmd.GetPID()
+
+    def terminate(self):
+        err = lldb.remote_platform.Kill(self._pid)
+        if err.Fail():
+            raise Exception("remote_platform.Kill(%d) failed: %s" % (self._pid, err))
+
 # From 2.7's subprocess.check_output() convenience function.
 # Return a tuple (stdoutdata, stderrdata).
 def system(commands, **kwargs):
@@ -956,8 +1024,7 @@
     def cleanupSubprocesses(self):
         # Ensure any subprocesses are cleaned up
         for p in self.subprocesses:
-            if p.poll() == None:
-                p.terminate()
+            p.terminate()
             del p
         del self.subprocesses[:]
         # Ensure any forked processes are cleaned up
@@ -974,11 +1041,8 @@
 
             otherwise the test suite will leak processes.
         """
-
-        # Don't display the stdout if not in TraceOn() mode.
-        proc = Popen([executable] + args,
-                     stdout = open(os.devnull) if not self.TraceOn() else None,
-                     stdin = PIPE)
+        proc = _RemoteProcess() if lldb.remote_platform else _LocalProcess(self.TraceOn())
+        proc.launch(executable, args)
         self.subprocesses.append(proc)
         return proc
 
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits

Reply via email to