[Lldb-commits] [lldb] r228230 - Extend SBPlatform with capability to launch/terminate a process remotely. Integrate this change into test framework in order to spawn processes on a remote target.

Oleksiy Vyalov ovyalov at google.com
Wed Feb 4 15:19:15 PST 2015


Author: ovyalov
Date: Wed Feb  4 17:19:15 2015
New Revision: 228230

URL: http://llvm.org/viewvc/llvm-project?rev=228230&view=rev
Log:
Extend SBPlatform with capability to launch/terminate a process remotely. Integrate this change into test framework in order to spawn processes on a remote target.

http://reviews.llvm.org/D7263


Added:
    lldb/trunk/include/lldb/API/SBLaunchInfo.h
    lldb/trunk/scripts/Python/interface/SBLaunchInfo.i
    lldb/trunk/source/API/SBLaunchInfo.cpp
Modified:
    lldb/trunk/include/lldb/API/SBPlatform.h
    lldb/trunk/include/lldb/API/SBTarget.h
    lldb/trunk/include/lldb/Target/Platform.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/scripts/Python/build-swig-Python.sh
    lldb/trunk/scripts/Python/buildSwigPython.py
    lldb/trunk/scripts/Python/interface/SBPlatform.i
    lldb/trunk/scripts/Python/interface/SBTarget.i
    lldb/trunk/scripts/lldb.swig
    lldb/trunk/source/API/CMakeLists.txt
    lldb/trunk/source/API/SBPlatform.cpp
    lldb/trunk/source/API/SBTarget.cpp
    lldb/trunk/source/CMakeLists.txt
    lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
    lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
    lldb/trunk/source/Target/Platform.cpp
    lldb/trunk/test/lldbtest.py

Added: lldb/trunk/include/lldb/API/SBLaunchInfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBLaunchInfo.h?rev=228230&view=auto
==============================================================================
--- lldb/trunk/include/lldb/API/SBLaunchInfo.h (added)
+++ lldb/trunk/include/lldb/API/SBLaunchInfo.h Wed Feb  4 17:19:15 2015
@@ -0,0 +1,186 @@
+//===-- SBLaunchInfo.h ------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBLaunchInfo_h_
+#define LLDB_SBLaunchInfo_h_
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+class SBPlatform;
+class SBTarget;
+
+class SBLaunchInfo
+{
+public:
+    SBLaunchInfo (const char **argv);
+
+    ~SBLaunchInfo();
+
+    lldb::pid_t
+    GetProcessID();
+
+    uint32_t
+    GetUserID();
+
+    uint32_t
+    GetGroupID();
+
+    bool
+    UserIDIsValid ();
+
+    bool
+    GroupIDIsValid ();
+
+    void
+    SetUserID (uint32_t uid);
+
+    void
+    SetGroupID (uint32_t gid);
+
+    SBFileSpec
+    GetExecutableFile ();
+
+    //----------------------------------------------------------------------
+    /// Set the executable file that will be used to launch the process and
+    /// optionally set it as the first argument in the argument vector.
+    ///
+    /// This only needs to be specified if clients wish to carefully control
+    /// the exact path will be used to launch a binary. If you create a
+    /// target with a symlink, that symlink will get resolved in the target
+    /// and the resolved path will get used to launch the process. Calling
+    /// this function can help you still launch your process using the
+    /// path of your choice.
+    ///
+    /// If this function is not called prior to launching with
+    /// SBTarget::Launch(...), the target will use the resolved executable
+    /// path that was used to create the target.
+    ///
+    /// @param[in] exe_file
+    ///     The override path to use when launching the executable.
+    ///
+    /// @param[in] add_as_first_arg
+    ///     If true, then the path will be inserted into the argument vector
+    ///     prior to launching. Otherwise the argument vector will be left
+    ///     alone.
+    //----------------------------------------------------------------------
+    void
+    SetExecutableFile (SBFileSpec exe_file, bool add_as_first_arg);
+
+
+    //----------------------------------------------------------------------
+    /// Get the listener that will be used to receive process events.
+    ///
+    /// If no listener has been set via a call to
+    /// SBLaunchInfo::SetListener(), then an invalid SBListener will be
+    /// returned (SBListener::IsValid() will return false). If a listener
+    /// has been set, then the valid listener object will be returned.
+    //----------------------------------------------------------------------
+    SBListener
+    GetListener ();
+
+    //----------------------------------------------------------------------
+    /// Set the listener that will be used to receive process events.
+    ///
+    /// By default the SBDebugger, which has a listener, that the SBTarget
+    /// belongs to will listen for the process events. Calling this function
+    /// allows a different listener to be used to listen for process events.
+    //----------------------------------------------------------------------
+    void
+    SetListener (SBListener &listener);
+
+    uint32_t
+    GetNumArguments ();
+
+    const char *
+    GetArgumentAtIndex (uint32_t idx);
+
+    void
+    SetArguments (const char **argv, bool append);
+
+    uint32_t
+    GetNumEnvironmentEntries ();
+
+    const char *
+    GetEnvironmentEntryAtIndex (uint32_t idx);
+
+    void
+    SetEnvironmentEntries (const char **envp, bool append);
+
+    void
+    Clear ();
+
+    const char *
+    GetWorkingDirectory () const;
+
+    void
+    SetWorkingDirectory (const char *working_dir);
+
+    uint32_t
+    GetLaunchFlags ();
+
+    void
+    SetLaunchFlags (uint32_t flags);
+
+    const char *
+    GetProcessPluginName ();
+
+    void
+    SetProcessPluginName (const char *plugin_name);
+
+    const char *
+    GetShell ();
+
+    void
+    SetShell (const char * path);
+
+    uint32_t
+    GetResumeCount ();
+
+    void
+    SetResumeCount (uint32_t c);
+
+    bool
+    AddCloseFileAction (int fd);
+
+    bool
+    AddDuplicateFileAction (int fd, int dup_fd);
+
+    bool
+    AddOpenFileAction (int fd, const char *path, bool read, bool write);
+
+    bool
+    AddSuppressFileAction (int fd, bool read, bool write);
+
+    void
+    SetLaunchEventData (const char *data);
+
+    const char *
+    GetLaunchEventData () const;
+
+    bool
+    GetDetachOnError() const;
+
+    void
+    SetDetachOnError(bool enable);
+
+protected:
+    friend class SBPlatform;
+    friend class SBTarget;
+
+    lldb_private::ProcessLaunchInfo &
+    ref ();
+
+    ProcessLaunchInfoSP m_opaque_sp;
+};
+
+} // namespace lldb
+
+#endif  // LLDB_SBLaunchInfo_h_

Modified: lldb/trunk/include/lldb/API/SBPlatform.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBPlatform.h?rev=228230&r1=228229&r2=228230&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBPlatform.h (original)
+++ lldb/trunk/include/lldb/API/SBPlatform.h Wed Feb  4 17:19:15 2015
@@ -12,11 +12,15 @@
 
 #include "lldb/API/SBDefines.h"
 
+#include <functional>
+
 struct PlatformConnectOptions;
 struct PlatformShellCommand;
 
 namespace lldb {
 
+    class SBLaunchInfo;
+
     class SBPlatformConnectOptions
     {
     public:
@@ -171,6 +175,12 @@ namespace lldb {
         Run (SBPlatformShellCommand &shell_command);
 
         SBError
+        Launch (SBLaunchInfo &launch_info);
+
+        SBError
+        Kill (const lldb::pid_t pid);
+
+        SBError
         MakeDirectory (const char *path, uint32_t file_permissions = eFilePermissionsDirectoryDefault);
 
         uint32_t
@@ -190,6 +200,9 @@ namespace lldb {
         void
         SetSP (const lldb::PlatformSP& platform_sp);
 
+        SBError
+        ExecuteConnected (const std::function<lldb_private::Error(const lldb::PlatformSP&)>& func);
+
         lldb::PlatformSP m_opaque_sp;
     };
 

Modified: lldb/trunk/include/lldb/API/SBTarget.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTarget.h?rev=228230&r1=228229&r2=228230&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBTarget.h (original)
+++ lldb/trunk/include/lldb/API/SBTarget.h Wed Feb  4 17:19:15 2015
@@ -15,6 +15,7 @@
 #include "lldb/API/SBBroadcaster.h"
 #include "lldb/API/SBFileSpec.h"
 #include "lldb/API/SBFileSpecList.h"
+#include "lldb/API/SBLaunchInfo.h"
 #include "lldb/API/SBSymbolContextList.h"
 #include "lldb/API/SBType.h"
 #include "lldb/API/SBValue.h"
@@ -24,166 +25,6 @@ namespace lldb {
 
 class SBPlatform;
 
-class SBLaunchInfo
-{
-public:
-    SBLaunchInfo (const char **argv);
-    
-    ~SBLaunchInfo();
-
-    uint32_t
-    GetUserID();
-    
-    uint32_t
-    GetGroupID();
-    
-    bool
-    UserIDIsValid ();
-    
-    bool
-    GroupIDIsValid ();
-    
-    void
-    SetUserID (uint32_t uid);
-    
-    void
-    SetGroupID (uint32_t gid);
-    
-    SBFileSpec
-    GetExecutableFile ();
-
-    //----------------------------------------------------------------------
-    /// Set the executable file that will be used to launch the process and
-    /// optionally set it as the first argument in the argument vector.
-    ///
-    /// This only needs to be specified if clients wish to carefully control
-    /// the exact path will be used to launch a binary. If you create a
-    /// target with a symlink, that symlink will get resolved in the target
-    /// and the resolved path will get used to launch the process. Calling
-    /// this function can help you still launch your process using the
-    /// path of your choice.
-    ///
-    /// If this function is not called prior to launching with
-    /// SBTarget::Launch(...), the target will use the resolved executable
-    /// path that was used to create the target.
-    ///
-    /// @param[in] exe_file
-    ///     The override path to use when launching the executable.
-    ///
-    /// @param[in] add_as_first_arg
-    ///     If true, then the path will be inserted into the argument vector
-    ///     prior to launching. Otherwise the argument vector will be left
-    ///     alone.
-    //----------------------------------------------------------------------
-    void
-    SetExecutableFile (SBFileSpec exe_file, bool add_as_first_arg);
-
-
-    //----------------------------------------------------------------------
-    /// Get the listener that will be used to receive process events.
-    ///
-    /// If no listener has been set via a call to
-    /// SBLaunchInfo::SetListener(), then an invalid SBListener will be
-    /// returned (SBListener::IsValid() will return false). If a listener
-    /// has been set, then the valid listener object will be returned.
-    //----------------------------------------------------------------------
-    SBListener
-    GetListener ();
-
-    //----------------------------------------------------------------------
-    /// Set the listener that will be used to receive process events.
-    ///
-    /// By default the SBDebugger, which has a listener, that the SBTarget
-    /// belongs to will listen for the process events. Calling this function
-    /// allows a different listener to be used to listen for process events.
-    //----------------------------------------------------------------------
-    void
-    SetListener (SBListener &listener);
-
-    uint32_t
-    GetNumArguments ();
-    
-    const char *
-    GetArgumentAtIndex (uint32_t idx);
-    
-    void
-    SetArguments (const char **argv, bool append);
-    
-    uint32_t
-    GetNumEnvironmentEntries ();
-    
-    const char *
-    GetEnvironmentEntryAtIndex (uint32_t idx);
-    
-    void
-    SetEnvironmentEntries (const char **envp, bool append);
-    
-    void
-    Clear ();
-    
-    const char *
-    GetWorkingDirectory () const;
-    
-    void
-    SetWorkingDirectory (const char *working_dir);
-    
-    uint32_t
-    GetLaunchFlags ();
-    
-    void
-    SetLaunchFlags (uint32_t flags);
-    
-    const char *
-    GetProcessPluginName ();
-    
-    void
-    SetProcessPluginName (const char *plugin_name);
-    
-    const char *
-    GetShell ();
-    
-    void
-    SetShell (const char * path);
-    
-    uint32_t
-    GetResumeCount ();
-    
-    void
-    SetResumeCount (uint32_t c);
-    
-    bool
-    AddCloseFileAction (int fd);
-    
-    bool
-    AddDuplicateFileAction (int fd, int dup_fd);
-    
-    bool
-    AddOpenFileAction (int fd, const char *path, bool read, bool write);
-    
-    bool
-    AddSuppressFileAction (int fd, bool read, bool write);
-    
-    void
-    SetLaunchEventData (const char *data);
-    
-    const char *
-    GetLaunchEventData () const;
-    
-    bool
-    GetDetachOnError() const;
-    
-    void
-    SetDetachOnError(bool enable);
-    
-protected:
-    friend class SBTarget;
-    
-    lldb_private::ProcessLaunchInfo &
-    ref ();
-
-    ProcessLaunchInfoSP m_opaque_sp;
-};
-
 class SBAttachInfo
 {
 public:

Modified: lldb/trunk/include/lldb/Target/Platform.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Platform.h?rev=228230&r1=228229&r2=228230&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Platform.h (original)
+++ lldb/trunk/include/lldb/Target/Platform.h Wed Feb  4 17:19:15 2015
@@ -380,6 +380,12 @@ namespace lldb_private {
         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.
         //------------------------------------------------------------------

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=228230&r1=228229&r2=228230&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Wed Feb  4 17:19:15 2015
@@ -92,6 +92,8 @@
 		23F4034D1926E0F60046DC9B /* NativeRegisterContextRegisterInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23F403481926CC250046DC9B /* NativeRegisterContextRegisterInfo.cpp */; };
 		25420ECD1A6490B8009ADBCB /* OptionValueChar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 25420ECC1A6490B8009ADBCB /* OptionValueChar.cpp */; };
 		25420ED21A649D88009ADBCB /* PipeBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 25420ED11A649D88009ADBCB /* PipeBase.cpp */; };
+		254FBB951A81AA7F00BD6378 /* SBLaunchInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 254FBB941A81AA7F00BD6378 /* SBLaunchInfo.cpp */; };
+		254FBB971A81B03100BD6378 /* SBLaunchInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 254FBB961A81B03100BD6378 /* SBLaunchInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		260157C61885F51C00F875CF /* libpanel.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 260157C41885F4FF00F875CF /* libpanel.dylib */; };
 		260157C71885F52500F875CF /* libpanel.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 260157C41885F4FF00F875CF /* libpanel.dylib */; };
 		260157C81885F53100F875CF /* libpanel.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 260157C41885F4FF00F875CF /* libpanel.dylib */; };
@@ -1168,6 +1170,9 @@
 		25420ECC1A6490B8009ADBCB /* OptionValueChar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OptionValueChar.cpp; path = source/Interpreter/OptionValueChar.cpp; sourceTree = "<group>"; };
 		25420ECE1A64911B009ADBCB /* OptionValueChar.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OptionValueChar.h; path = include/lldb/Interpreter/OptionValueChar.h; sourceTree = "<group>"; };
 		25420ED11A649D88009ADBCB /* PipeBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PipeBase.cpp; sourceTree = "<group>"; };
+		254FBB921A81AA5200BD6378 /* SBLaunchInfo.i */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBLaunchInfo.i; sourceTree = "<group>"; };
+		254FBB941A81AA7F00BD6378 /* SBLaunchInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBLaunchInfo.cpp; path = source/API/SBLaunchInfo.cpp; sourceTree = "<group>"; };
+		254FBB961A81B03100BD6378 /* SBLaunchInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBLaunchInfo.h; path = include/lldb/API/SBLaunchInfo.h; sourceTree = "<group>"; };
 		260157C41885F4FF00F875CF /* libpanel.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpanel.dylib; path = /usr/lib/libpanel.dylib; sourceTree = "<absolute>"; };
 		260223E7115F06D500A601A2 /* SBCommunication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBCommunication.h; path = include/lldb/API/SBCommunication.h; sourceTree = "<group>"; };
 		260223E8115F06E500A601A2 /* SBCommunication.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBCommunication.cpp; path = source/API/SBCommunication.cpp; sourceTree = "<group>"; };
@@ -3028,6 +3033,7 @@
 		2611FEEE142D83060017FEA3 /* interface */ = {
 			isa = PBXGroup;
 			children = (
+				254FBB921A81AA5200BD6378 /* SBLaunchInfo.i */,
 				2611FEEF142D83060017FEA3 /* SBAddress.i */,
 				2611FEF0142D83060017FEA3 /* SBBlock.i */,
 				2611FEF1142D83060017FEA3 /* SBBreakpoint.i */,
@@ -3097,6 +3103,8 @@
 		262D3190111B4341004E6F88 /* API */ = {
 			isa = PBXGroup;
 			children = (
+				254FBB961A81B03100BD6378 /* SBLaunchInfo.h */,
+				254FBB941A81AA7F00BD6378 /* SBLaunchInfo.cpp */,
 				2611FEEE142D83060017FEA3 /* interface */,
 				26BC7C2510F1B3BC00F91463 /* lldb-defines.h */,
 				26BC7C2610F1B3BC00F91463 /* lldb-enumerations.h */,
@@ -5040,6 +5048,7 @@
 				9AC7038E117674FB0086C050 /* SBInstruction.h in Headers */,
 				9AC70390117675270086C050 /* SBInstructionList.h in Headers */,
 				26DE205911618FE700A093E2 /* SBLineEntry.h in Headers */,
+				254FBB971A81B03100BD6378 /* SBLaunchInfo.h in Headers */,
 				AF0EBBED185941360059E52F /* SBQueueItem.h in Headers */,
 				26680227115FD13D008E1FE4 /* SBListener.h in Headers */,
 				26DE204F11618E9800A093E2 /* SBModule.h in Headers */,
@@ -5644,6 +5653,7 @@
 				9452573A16262D0200325455 /* SBDeclaration.cpp in Sources */,
 				4CE4F675162C973F00F75CB3 /* SBExpressionOptions.cpp in Sources */,
 				AF9107EE168570D200DBCD3C /* RegisterContextDarwin_arm64.cpp in Sources */,
+				254FBB951A81AA7F00BD6378 /* SBLaunchInfo.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Modified: lldb/trunk/scripts/Python/build-swig-Python.sh
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/build-swig-Python.sh?rev=228230&r1=228229&r2=228230&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/build-swig-Python.sh (original)
+++ lldb/trunk/scripts/Python/build-swig-Python.sh Wed Feb  4 17:19:15 2015
@@ -99,6 +99,7 @@ HEADER_FILES="${SRC_ROOT}/include/lldb/l
 " ${SRC_ROOT}/include/lldb/API/SBHostOS.h"\
 " ${SRC_ROOT}/include/lldb/API/SBInstruction.h"\
 " ${SRC_ROOT}/include/lldb/API/SBInstructionList.h"\
+" ${SRC_ROOT}/include/lldb/API/SBLaunchInfo.h"\
 " ${SRC_ROOT}/include/lldb/API/SBLineEntry.h"\
 " ${SRC_ROOT}/include/lldb/API/SBListener.h"\
 " ${SRC_ROOT}/include/lldb/API/SBModule.h"\
@@ -150,6 +151,7 @@ INTERFACE_FILES="${SRC_ROOT}/scripts/Pyt
 " ${SRC_ROOT}/scripts/Python/interface/SBHostOS.i"\
 " ${SRC_ROOT}/scripts/Python/interface/SBInstruction.i"\
 " ${SRC_ROOT}/scripts/Python/interface/SBInstructionList.i"\
+" ${SRC_ROOT}/scripts/Python/interface/SBLaunchInfo.i"\
 " ${SRC_ROOT}/scripts/Python/interface/SBLineEntry.i"\
 " ${SRC_ROOT}/scripts/Python/interface/SBListener.i"\
 " ${SRC_ROOT}/scripts/Python/interface/SBModule.i"\

Modified: lldb/trunk/scripts/Python/buildSwigPython.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/buildSwigPython.py?rev=228230&r1=228229&r2=228230&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/buildSwigPython.py (original)
+++ lldb/trunk/scripts/Python/buildSwigPython.py Wed Feb  4 17:19:15 2015
@@ -101,6 +101,7 @@ def get_header_files( vDictArgs ):
 						"/include/lldb/API/SBInputReader.h",
 						"/include/lldb/API/SBInstruction.h",
 						"/include/lldb/API/SBInstructionList.h",
+            "/include/lldb/API/SBLaunchInfo.h",
 						"/include/lldb/API/SBLineEntry.h",
 						"/include/lldb/API/SBListener.h",
 						"/include/lldb/API/SBModule.h",
@@ -177,6 +178,7 @@ def get_interface_files( vDictArgs ):
 						"/scripts/Python/interface/SBInputReader.i",
 						"/scripts/Python/interface/SBInstruction.i",
 						"/scripts/Python/interface/SBInstructionList.i",
+            "/scripts/Python/interface/SBLaunchInfo.i",
 						"/scripts/Python/interface/SBLineEntry.i",
 						"/scripts/Python/interface/SBListener.i",
 						"/scripts/Python/interface/SBModule.i",

Added: lldb/trunk/scripts/Python/interface/SBLaunchInfo.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBLaunchInfo.i?rev=228230&view=auto
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBLaunchInfo.i (added)
+++ lldb/trunk/scripts/Python/interface/SBLaunchInfo.i Wed Feb  4 17:19:15 2015
@@ -0,0 +1,126 @@
+//===-- SWIG Interface for SBLaunchInfo--------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+namespace lldb {
+
+class SBLaunchInfo
+{
+public:
+    SBLaunchInfo (const char **argv);
+
+    pid_t
+    GetProcessID();
+
+    uint32_t
+    GetUserID();
+
+    uint32_t
+    GetGroupID();
+
+    bool
+    UserIDIsValid ();
+
+    bool
+    GroupIDIsValid ();
+
+    void
+    SetUserID (uint32_t uid);
+
+    void
+    SetGroupID (uint32_t gid);
+
+    lldb::SBFileSpec
+    GetExecutableFile ();
+
+    void
+    SetExecutableFile (lldb::SBFileSpec exe_file, bool add_as_first_arg);
+
+    lldb::SBListener
+    GetListener ();
+
+    void
+    SetListener (lldb::SBListener &listener);
+
+    uint32_t
+    GetNumArguments ();
+
+    const char *
+    GetArgumentAtIndex (uint32_t idx);
+
+    void
+    SetArguments (const char **argv, bool append);
+
+    uint32_t
+    GetNumEnvironmentEntries ();
+
+    const char *
+    GetEnvironmentEntryAtIndex (uint32_t idx);
+
+    void
+    SetEnvironmentEntries (const char **envp, bool append);
+
+    void
+    Clear ();
+
+    const char *
+    GetWorkingDirectory () const;
+
+    void
+    SetWorkingDirectory (const char *working_dir);
+
+    uint32_t
+    GetLaunchFlags ();
+
+    void
+    SetLaunchFlags (uint32_t flags);
+
+    const char *
+    GetProcessPluginName ();
+
+    void
+    SetProcessPluginName (const char *plugin_name);
+
+    const char *
+    GetShell ();
+
+    void
+    SetShell (const char * path);
+
+    uint32_t
+    GetResumeCount ();
+
+    void
+    SetResumeCount (uint32_t c);
+
+    bool
+    AddCloseFileAction (int fd);
+
+    bool
+    AddDuplicateFileAction (int fd, int dup_fd);
+
+    bool
+    AddOpenFileAction (int fd, const char *path, bool read, bool write);
+
+    bool
+    AddSuppressFileAction (int fd, bool read, bool write);
+
+    void
+    SetLaunchEventData (const char *data);
+
+    const char *
+    GetLaunchEventData () const;
+
+    bool
+    GetDetachOnError() const;
+
+    void
+    SetDetachOnError(bool enable);
+};
+
+} // namespace lldb

Modified: lldb/trunk/scripts/Python/interface/SBPlatform.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBPlatform.i?rev=228230&r1=228229&r2=228230&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBPlatform.i (original)
+++ lldb/trunk/scripts/Python/interface/SBPlatform.i Wed Feb  4 17:19:15 2015
@@ -174,6 +174,12 @@ public:
     Run (lldb::SBPlatformShellCommand &shell_command);
 
     lldb::SBError
+    Launch (lldb::SBLaunchInfo &launch_info);
+
+    lldb::SBError
+    Kill (const lldb::pid_t pid);
+
+    lldb::SBError
     MakeDirectory (const char *path, uint32_t file_permissions = lldb::eFilePermissionsDirectoryDefault);
     
     uint32_t

Modified: lldb/trunk/scripts/Python/interface/SBTarget.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBTarget.i?rev=228230&r1=228229&r2=228230&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBTarget.i (original)
+++ lldb/trunk/scripts/Python/interface/SBTarget.i Wed Feb  4 17:19:15 2015
@@ -9,117 +9,6 @@
 
 namespace lldb {
 
-class SBLaunchInfo
-{
-public:
-    SBLaunchInfo (const char **argv);
-    
-    uint32_t
-    GetUserID();
-    
-    uint32_t
-    GetGroupID();
-    
-    bool
-    UserIDIsValid ();
-    
-    bool
-    GroupIDIsValid ();
-    
-    void
-    SetUserID (uint32_t uid);
-    
-    void
-    SetGroupID (uint32_t gid);
-    
-    lldb::SBFileSpec
-    GetExecutableFile ();
-    
-    void
-    SetExecutableFile (lldb::SBFileSpec exe_file, bool add_as_first_arg);
-
-    lldb::SBListener
-    GetListener ();
-
-    void
-    SetListener (lldb::SBListener &listener);
-
-    uint32_t
-    GetNumArguments ();
-    
-    const char *
-    GetArgumentAtIndex (uint32_t idx);
-    
-    void
-    SetArguments (const char **argv, bool append);
-    
-    uint32_t
-    GetNumEnvironmentEntries ();
-    
-    const char *
-    GetEnvironmentEntryAtIndex (uint32_t idx);
-    
-    void
-    SetEnvironmentEntries (const char **envp, bool append);
-    
-    void
-    Clear ();
-    
-    const char *
-    GetWorkingDirectory () const;
-    
-    void
-    SetWorkingDirectory (const char *working_dir);
-    
-    uint32_t
-    GetLaunchFlags ();
-    
-    void
-    SetLaunchFlags (uint32_t flags);
-    
-    const char *
-    GetProcessPluginName ();
-    
-    void
-    SetProcessPluginName (const char *plugin_name);
-    
-    const char *
-    GetShell ();
-    
-    void
-    SetShell (const char * path);
-    
-    uint32_t
-    GetResumeCount ();
-    
-    void
-    SetResumeCount (uint32_t c);
-    
-    bool
-    AddCloseFileAction (int fd);
-    
-    bool
-    AddDuplicateFileAction (int fd, int dup_fd);
-    
-    bool
-    AddOpenFileAction (int fd, const char *path, bool read, bool write);
-    
-    bool
-    AddSuppressFileAction (int fd, bool read, bool write);
-
-    void
-    SetLaunchEventData (const char *data);
-    
-    const char *
-    GetLaunchEventData () const;
-    
-    bool
-    GetDetachOnError() const;
-    
-    void
-    SetDetachOnError(bool enable);
-};
-
 class SBAttachInfo
 {
 public:

Modified: lldb/trunk/scripts/lldb.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/lldb.swig?rev=228230&r1=228229&r2=228230&view=diff
==============================================================================
--- lldb/trunk/scripts/lldb.swig (original)
+++ lldb/trunk/scripts/lldb.swig Wed Feb  4 17:19:15 2015
@@ -75,6 +75,7 @@ import os
 #include "lldb/API/SBHostOS.h"
 #include "lldb/API/SBInstruction.h"
 #include "lldb/API/SBInstructionList.h"
+#include "lldb/API/SBLaunchInfo.h"
 #include "lldb/API/SBLineEntry.h"
 #include "lldb/API/SBListener.h"
 #include "lldb/API/SBModule.h"
@@ -149,6 +150,7 @@ import os
 %include "./Python/interface/SBHostOS.i"
 %include "./Python/interface/SBInstruction.i"
 %include "./Python/interface/SBInstructionList.i"
+%include "./Python/interface/SBLaunchInfo.i"
 %include "./Python/interface/SBLineEntry.i"
 %include "./Python/interface/SBListener.i"
 %include "./Python/interface/SBModule.i"

Modified: lldb/trunk/source/API/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/CMakeLists.txt?rev=228230&r1=228229&r2=228230&view=diff
==============================================================================
--- lldb/trunk/source/API/CMakeLists.txt (original)
+++ lldb/trunk/source/API/CMakeLists.txt Wed Feb  4 17:19:15 2015
@@ -27,6 +27,7 @@ add_lldb_library(lldbAPI
   SBHostOS.cpp
   SBInstruction.cpp
   SBInstructionList.cpp
+  SBLaunchInfo.cpp
   SBLineEntry.cpp
   SBListener.cpp
   SBModule.cpp

Added: lldb/trunk/source/API/SBLaunchInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBLaunchInfo.cpp?rev=228230&view=auto
==============================================================================
--- lldb/trunk/source/API/SBLaunchInfo.cpp (added)
+++ lldb/trunk/source/API/SBLaunchInfo.cpp Wed Feb  4 17:19:15 2015
@@ -0,0 +1,278 @@
+//===-- SBLaunchInfo.cpp ----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+#include "lldb/API/SBLaunchInfo.h"
+
+#include "lldb/API/SBFileSpec.h"
+#include "lldb/API/SBListener.h"
+#include "lldb/Target/ProcessLaunchInfo.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+SBLaunchInfo::SBLaunchInfo (const char **argv) :
+    m_opaque_sp(new ProcessLaunchInfo())
+{
+    m_opaque_sp->GetFlags().Reset (eLaunchFlagDebug | eLaunchFlagDisableASLR);
+    if (argv && argv[0])
+        m_opaque_sp->GetArguments().SetArguments(argv);
+}
+
+SBLaunchInfo::~SBLaunchInfo()
+{
+}
+
+lldb_private::ProcessLaunchInfo &
+SBLaunchInfo::ref ()
+{
+    return *m_opaque_sp;
+}
+
+lldb::pid_t
+SBLaunchInfo::GetProcessID()
+{
+    return m_opaque_sp->GetProcessID();
+}
+
+uint32_t
+SBLaunchInfo::GetUserID()
+{
+    return m_opaque_sp->GetUserID();
+}
+
+uint32_t
+SBLaunchInfo::GetGroupID()
+{
+    return m_opaque_sp->GetGroupID();
+}
+
+bool
+SBLaunchInfo::UserIDIsValid ()
+{
+    return m_opaque_sp->UserIDIsValid();
+}
+
+bool
+SBLaunchInfo::GroupIDIsValid ()
+{
+    return m_opaque_sp->GroupIDIsValid();
+}
+
+void
+SBLaunchInfo::SetUserID (uint32_t uid)
+{
+    m_opaque_sp->SetUserID (uid);
+}
+
+void
+SBLaunchInfo::SetGroupID (uint32_t gid)
+{
+    m_opaque_sp->SetGroupID (gid);
+}
+
+SBFileSpec
+SBLaunchInfo::GetExecutableFile ()
+{
+    return SBFileSpec (m_opaque_sp->GetExecutableFile());
+}
+
+void
+SBLaunchInfo::SetExecutableFile (SBFileSpec exe_file, bool add_as_first_arg)
+{
+    m_opaque_sp->SetExecutableFile(exe_file.ref(), add_as_first_arg);
+}
+
+SBListener
+SBLaunchInfo::GetListener ()
+{
+    return SBListener(m_opaque_sp->GetListener());
+}
+
+void
+SBLaunchInfo::SetListener (SBListener &listener)
+{
+    m_opaque_sp->SetListener(listener.GetSP());
+}
+
+uint32_t
+SBLaunchInfo::GetNumArguments ()
+{
+    return m_opaque_sp->GetArguments().GetArgumentCount();
+}
+
+const char *
+SBLaunchInfo::GetArgumentAtIndex (uint32_t idx)
+{
+    return m_opaque_sp->GetArguments().GetArgumentAtIndex(idx);
+}
+
+void
+SBLaunchInfo::SetArguments (const char **argv, bool append)
+{
+    if (append)
+    {
+        if (argv)
+            m_opaque_sp->GetArguments().AppendArguments(argv);
+    }
+    else
+    {
+        if (argv)
+            m_opaque_sp->GetArguments().SetArguments(argv);
+        else
+            m_opaque_sp->GetArguments().Clear();
+    }
+}
+
+uint32_t
+SBLaunchInfo::GetNumEnvironmentEntries ()
+{
+    return m_opaque_sp->GetEnvironmentEntries().GetArgumentCount();
+}
+
+const char *
+SBLaunchInfo::GetEnvironmentEntryAtIndex (uint32_t idx)
+{
+    return m_opaque_sp->GetEnvironmentEntries().GetArgumentAtIndex(idx);
+}
+
+void
+SBLaunchInfo::SetEnvironmentEntries (const char **envp, bool append)
+{
+    if (append)
+    {
+        if (envp)
+            m_opaque_sp->GetEnvironmentEntries().AppendArguments(envp);
+    }
+    else
+    {
+        if (envp)
+            m_opaque_sp->GetEnvironmentEntries().SetArguments(envp);
+        else
+            m_opaque_sp->GetEnvironmentEntries().Clear();
+    }
+}
+
+void
+SBLaunchInfo::Clear ()
+{
+    m_opaque_sp->Clear();
+}
+
+const char *
+SBLaunchInfo::GetWorkingDirectory () const
+{
+    return m_opaque_sp->GetWorkingDirectory();
+}
+
+void
+SBLaunchInfo::SetWorkingDirectory (const char *working_dir)
+{
+    m_opaque_sp->SetWorkingDirectory(working_dir);
+}
+
+uint32_t
+SBLaunchInfo::GetLaunchFlags ()
+{
+    return m_opaque_sp->GetFlags().Get();
+}
+
+void
+SBLaunchInfo::SetLaunchFlags (uint32_t flags)
+{
+    m_opaque_sp->GetFlags().Reset(flags);
+}
+
+const char *
+SBLaunchInfo::GetProcessPluginName ()
+{
+    return m_opaque_sp->GetProcessPluginName();
+}
+
+void
+SBLaunchInfo::SetProcessPluginName (const char *plugin_name)
+{
+    return m_opaque_sp->SetProcessPluginName (plugin_name);
+}
+
+const char *
+SBLaunchInfo::GetShell ()
+{
+    // Constify this string so that it is saved in the string pool.  Otherwise
+    // it would be freed when this function goes out of scope.
+    ConstString shell(m_opaque_sp->GetShell().GetPath().c_str());
+    return shell.AsCString();
+}
+
+void
+SBLaunchInfo::SetShell (const char * path)
+{
+    m_opaque_sp->SetShell (FileSpec(path, false));
+}
+
+uint32_t
+SBLaunchInfo::GetResumeCount ()
+{
+    return m_opaque_sp->GetResumeCount();
+}
+
+void
+SBLaunchInfo::SetResumeCount (uint32_t c)
+{
+    m_opaque_sp->SetResumeCount (c);
+}
+
+bool
+SBLaunchInfo::AddCloseFileAction (int fd)
+{
+    return m_opaque_sp->AppendCloseFileAction(fd);
+}
+
+bool
+SBLaunchInfo::AddDuplicateFileAction (int fd, int dup_fd)
+{
+    return m_opaque_sp->AppendDuplicateFileAction(fd, dup_fd);
+}
+
+bool
+SBLaunchInfo::AddOpenFileAction (int fd, const char *path, bool read, bool write)
+{
+    return m_opaque_sp->AppendOpenFileAction(fd, path, read, write);
+}
+
+bool
+SBLaunchInfo::AddSuppressFileAction (int fd, bool read, bool write)
+{
+    return m_opaque_sp->AppendSuppressFileAction(fd, read, write);
+}
+
+void
+SBLaunchInfo::SetLaunchEventData (const char *data)
+{
+    m_opaque_sp->SetLaunchEventData (data);
+}
+
+const char *
+SBLaunchInfo::GetLaunchEventData () const
+{
+    return m_opaque_sp->GetLaunchEventData ();
+}
+
+void
+SBLaunchInfo::SetDetachOnError (bool enable)
+{
+    m_opaque_sp->SetDetachOnError (enable);
+}
+
+bool
+SBLaunchInfo::GetDetachOnError () const
+{
+    return m_opaque_sp->GetDetachOnError ();
+}

Modified: lldb/trunk/source/API/SBPlatform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBPlatform.cpp?rev=228230&r1=228229&r2=228230&view=diff
==============================================================================
--- lldb/trunk/source/API/SBPlatform.cpp (original)
+++ lldb/trunk/source/API/SBPlatform.cpp Wed Feb  4 17:19:15 2015
@@ -10,6 +10,7 @@
 #include "lldb/API/SBPlatform.h"
 #include "lldb/API/SBError.h"
 #include "lldb/API/SBFileSpec.h"
+#include "lldb/API/SBLaunchInfo.h"
 #include "lldb/Core/ArchSpec.h"
 #include "lldb/Core/Error.h"
 #include "lldb/Host/File.h"
@@ -17,6 +18,8 @@
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Platform.h"
 
+#include <functional>
+
 using namespace lldb;
 using namespace lldb_private;
 
@@ -484,104 +487,108 @@ SBError
 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 (SBLaunchInfo &launch_info)
+{
+    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;
+            return platform_sp->LaunchProcess(launch_info.ref());
+        });
 }
 
 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())
-        {
-            sb_error.ref() = platform_sp->Install(src.ref(), dst.ref());
-        }
-        else
+    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;
+            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

Modified: lldb/trunk/source/API/SBTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTarget.cpp?rev=228230&r1=228229&r2=228230&view=diff
==============================================================================
--- lldb/trunk/source/API/SBTarget.cpp (original)
+++ lldb/trunk/source/API/SBTarget.cpp Wed Feb  4 17:19:15 2015
@@ -66,259 +66,6 @@ using namespace lldb_private;
 
 #define DEFAULT_DISASM_BYTE_SIZE 32
 
-SBLaunchInfo::SBLaunchInfo (const char **argv) : 
-    m_opaque_sp(new ProcessLaunchInfo())
-{
-    m_opaque_sp->GetFlags().Reset (eLaunchFlagDebug | eLaunchFlagDisableASLR);
-    if (argv && argv[0])
-        m_opaque_sp->GetArguments().SetArguments(argv);
-}
-
-SBLaunchInfo::~SBLaunchInfo()
-{
-}
-
-lldb_private::ProcessLaunchInfo &
-SBLaunchInfo::ref ()
-{
-    return *m_opaque_sp;
-}
-
-
-uint32_t
-SBLaunchInfo::GetUserID()
-{
-    return m_opaque_sp->GetUserID();
-}
-
-uint32_t
-SBLaunchInfo::GetGroupID()
-{
-    return m_opaque_sp->GetGroupID();
-}
-
-bool
-SBLaunchInfo::UserIDIsValid ()
-{
-    return m_opaque_sp->UserIDIsValid();
-}
-
-bool
-SBLaunchInfo::GroupIDIsValid ()
-{
-    return m_opaque_sp->GroupIDIsValid();
-}
-
-void
-SBLaunchInfo::SetUserID (uint32_t uid)
-{
-    m_opaque_sp->SetUserID (uid);
-}
-
-void
-SBLaunchInfo::SetGroupID (uint32_t gid)
-{
-    m_opaque_sp->SetGroupID (gid);
-}
-
-SBFileSpec
-SBLaunchInfo::GetExecutableFile ()
-{
-    return SBFileSpec (m_opaque_sp->GetExecutableFile());
-}
-
-void
-SBLaunchInfo::SetExecutableFile (SBFileSpec exe_file, bool add_as_first_arg)
-{
-    m_opaque_sp->SetExecutableFile(exe_file.ref(), add_as_first_arg);
-}
-
-SBListener
-SBLaunchInfo::GetListener ()
-{
-    return SBListener(m_opaque_sp->GetListener());
-}
-
-void
-SBLaunchInfo::SetListener (SBListener &listener)
-{
-    m_opaque_sp->SetListener(listener.GetSP());
-}
-
-uint32_t
-SBLaunchInfo::GetNumArguments ()
-{
-    return m_opaque_sp->GetArguments().GetArgumentCount();
-}
-
-const char *
-SBLaunchInfo::GetArgumentAtIndex (uint32_t idx)
-{
-    return m_opaque_sp->GetArguments().GetArgumentAtIndex(idx);
-}
-
-void
-SBLaunchInfo::SetArguments (const char **argv, bool append)
-{
-    if (append)
-    {
-        if (argv)
-            m_opaque_sp->GetArguments().AppendArguments(argv);
-    }
-    else
-    {
-        if (argv)
-            m_opaque_sp->GetArguments().SetArguments(argv);
-        else
-            m_opaque_sp->GetArguments().Clear();
-    }
-}
-
-uint32_t
-SBLaunchInfo::GetNumEnvironmentEntries ()
-{
-    return m_opaque_sp->GetEnvironmentEntries().GetArgumentCount();
-}
-
-const char *
-SBLaunchInfo::GetEnvironmentEntryAtIndex (uint32_t idx)
-{
-    return m_opaque_sp->GetEnvironmentEntries().GetArgumentAtIndex(idx);
-}
-
-void
-SBLaunchInfo::SetEnvironmentEntries (const char **envp, bool append)
-{
-    if (append)
-    {
-        if (envp)
-            m_opaque_sp->GetEnvironmentEntries().AppendArguments(envp);
-    }
-    else
-    {
-        if (envp)
-            m_opaque_sp->GetEnvironmentEntries().SetArguments(envp);
-        else
-            m_opaque_sp->GetEnvironmentEntries().Clear();
-    }
-}
-
-void
-SBLaunchInfo::Clear ()
-{
-    m_opaque_sp->Clear();
-}
-
-const char *
-SBLaunchInfo::GetWorkingDirectory () const
-{
-    return m_opaque_sp->GetWorkingDirectory();
-}
-
-void
-SBLaunchInfo::SetWorkingDirectory (const char *working_dir)
-{
-    m_opaque_sp->SetWorkingDirectory(working_dir);
-}
-
-uint32_t
-SBLaunchInfo::GetLaunchFlags ()
-{
-    return m_opaque_sp->GetFlags().Get();
-}
-
-void
-SBLaunchInfo::SetLaunchFlags (uint32_t flags)
-{
-    m_opaque_sp->GetFlags().Reset(flags);
-}
-
-const char *
-SBLaunchInfo::GetProcessPluginName ()
-{
-    return m_opaque_sp->GetProcessPluginName();
-}
-
-void
-SBLaunchInfo::SetProcessPluginName (const char *plugin_name)
-{
-    return m_opaque_sp->SetProcessPluginName (plugin_name);
-}
-
-const char *
-SBLaunchInfo::GetShell ()
-{
-    // Constify this string so that it is saved in the string pool.  Otherwise
-    // it would be freed when this function goes out of scope.
-    ConstString shell(m_opaque_sp->GetShell().GetPath().c_str());
-    return shell.AsCString();
-}
-
-void
-SBLaunchInfo::SetShell (const char * path)
-{
-    m_opaque_sp->SetShell (FileSpec(path, false));
-}
-
-uint32_t
-SBLaunchInfo::GetResumeCount ()
-{
-    return m_opaque_sp->GetResumeCount();
-}
-
-void
-SBLaunchInfo::SetResumeCount (uint32_t c)
-{
-    m_opaque_sp->SetResumeCount (c);
-}
-
-bool
-SBLaunchInfo::AddCloseFileAction (int fd)
-{
-    return m_opaque_sp->AppendCloseFileAction(fd);
-}
-
-bool
-SBLaunchInfo::AddDuplicateFileAction (int fd, int dup_fd)
-{
-    return m_opaque_sp->AppendDuplicateFileAction(fd, dup_fd);
-}
-
-bool
-SBLaunchInfo::AddOpenFileAction (int fd, const char *path, bool read, bool write)
-{
-    return m_opaque_sp->AppendOpenFileAction(fd, path, read, write);
-}
-
-bool
-SBLaunchInfo::AddSuppressFileAction (int fd, bool read, bool write)
-{
-    return m_opaque_sp->AppendSuppressFileAction(fd, read, write);
-}
-
-void
-SBLaunchInfo::SetLaunchEventData (const char *data)
-{
-    m_opaque_sp->SetLaunchEventData (data);
-}
-
-const char *
-SBLaunchInfo::GetLaunchEventData () const
-{
-    return m_opaque_sp->GetLaunchEventData ();
-}
-
-void
-SBLaunchInfo::SetDetachOnError (bool enable)
-{
-    m_opaque_sp->SetDetachOnError (enable);
-}
-
-bool
-SBLaunchInfo::GetDetachOnError () const
-{
-    return m_opaque_sp->GetDetachOnError ();
-}
 
 SBAttachInfo::SBAttachInfo () :
     m_opaque_sp (new ProcessAttachInfo())

Modified: lldb/trunk/source/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/CMakeLists.txt?rev=228230&r1=228229&r2=228230&view=diff
==============================================================================
--- lldb/trunk/source/CMakeLists.txt (original)
+++ lldb/trunk/source/CMakeLists.txt Wed Feb  4 17:19:15 2015
@@ -81,6 +81,7 @@ add_lldb_library(liblldb SHARED
   API/SBHostOS.cpp
   API/SBInstruction.cpp
   API/SBInstructionList.cpp
+  API/SBLaunchInfo.cpp
   API/SBLineEntry.cpp
   API/SBListener.cpp
   API/SBModule.cpp

Modified: lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp?rev=228230&r1=228229&r2=228230&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp Wed Feb  4 17:19:15 2015
@@ -430,14 +430,30 @@ PlatformRemoteGDBServer::LaunchProcess (
 {
     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__);
 
-    m_gdb_client.SetSTDIN ("/dev/null");
-    m_gdb_client.SetSTDOUT ("/dev/null");
-    m_gdb_client.SetSTDERR ("/dev/null");
+    auto num_file_actions = launch_info.GetNumFileActions ();
+    for (decltype(num_file_actions) i = 0; i < num_file_actions; ++i)
+    {
+        const auto file_action = launch_info.GetFileActionAtIndex (i);
+        if (file_action->GetAction () != FileAction::eFileActionOpen)
+            continue;
+        switch(file_action->GetFD())
+        {
+        case STDIN_FILENO:
+            m_gdb_client.SetSTDIN (file_action->GetPath());
+            break;
+        case STDOUT_FILENO:
+            m_gdb_client.SetSTDOUT (file_action->GetPath());
+            break;
+        case STDERR_FILENO:
+            m_gdb_client.SetSTDERR (file_action->GetPath());
+            break;
+        }
+    }
+
     m_gdb_client.SetDisableASLR (launch_info.GetFlags().Test (eLaunchFlagDisableASLR));
     m_gdb_client.SetDetachOnError (launch_info.GetFlags().Test (eLaunchFlagDetachOnError));
     
@@ -475,7 +491,7 @@ PlatformRemoteGDBServer::LaunchProcess (
         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 +502,7 @@ PlatformRemoteGDBServer::LaunchProcess (
             {
                 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 +519,14 @@ PlatformRemoteGDBServer::LaunchProcess (
     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,

Modified: lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h?rev=228230&r1=228229&r2=228230&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h (original)
+++ lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h Wed Feb  4 17:19:15 2015
@@ -86,7 +86,10 @@ public:
 
     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,

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp?rev=228230&r1=228229&r2=228230&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Wed Feb  4 17:19:15 2015
@@ -1211,13 +1211,13 @@ GDBRemoteCommunicationClient::SendInterr
 }
 
 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 @@ GDBRemoteCommunicationClient::GetProcess
 }
 
 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 ();
 

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h?rev=228230&r1=228229&r2=228230&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h Wed Feb  4 17:19:15 2015
@@ -100,7 +100,7 @@ public:
                    bool &timed_out);
 
     lldb::pid_t
-    GetCurrentProcessID ();
+    GetCurrentProcessID (bool allow_lazy = true);
 
     bool
     GetLaunchSuccess (std::string &error_str);
@@ -525,7 +525,7 @@ protected:
                                         StringExtractorGDBRemote &response);
 
     bool
-    GetCurrentProcessInfo ();
+    GetCurrentProcessInfo (bool allow_lazy_pid = true);
 
     bool
     GetGDBServerVersion();

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=228230&r1=228229&r2=228230&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp Wed Feb  4 17:19:15 2015
@@ -607,14 +607,12 @@ GDBRemoteCommunicationServer::LaunchPlat
 
     // 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;
@@ -1437,23 +1435,33 @@ CreateProcessInfoResponse_DebugServerSty
 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

Modified: lldb/trunk/source/Target/Platform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Platform.cpp?rev=228230&r1=228229&r2=228230&view=diff
==============================================================================
--- lldb/trunk/source/Target/Platform.cpp (original)
+++ lldb/trunk/source/Target/Platform.cpp Wed Feb  4 17:19:15 2015
@@ -1103,6 +1103,20 @@ Platform::LaunchProcess (ProcessLaunchIn
     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,

Modified: lldb/trunk/test/lldbtest.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=228230&r1=228229&r2=228230&view=diff
==============================================================================
--- lldb/trunk/test/lldbtest.py (original)
+++ lldb/trunk/test/lldbtest.py Wed Feb  4 17:19:15 2015
@@ -31,6 +31,7 @@ OK
 $ 
 """
 
+import abc
 import os, sys, traceback
 import os.path
 import re
@@ -41,6 +42,7 @@ import time
 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,78 @@ class recording(StringIO.StringIO):
             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))
+
+        dst_file_spec = lldb.SBFileSpec(dst_path, False)
+        err = lldb.remote_platform.Install(lldb.SBFileSpec(src_path, True),
+                                           dst_file_spec)
+        if err.Fail():
+            raise Exception("remote_platform.Install('%s', '%s') failed: %s" % (src_path, dst_path, err))
+
+        launch_info = lldb.SBLaunchInfo(args)
+        launch_info.SetExecutableFile(dst_file_spec, True)
+        launch_info.SetWorkingDirectory(remote_work_dir)
+
+        # Redirect stdout and stderr to /dev/null
+        launch_info.AddSuppressFileAction(1, False, True)
+        launch_info.AddSuppressFileAction(2, False, True)
+
+        err = lldb.remote_platform.Launch(launch_info)
+        if err.Fail():
+            raise Exception("remote_platform.Launch('%s', '%s') failed: %s" % (dst_path, args, err))
+        self._pid = launch_info.GetProcessID()
+
+    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):
@@ -961,8 +1035,7 @@ class Base(unittest2.TestCase):
     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
@@ -979,11 +1052,8 @@ class Base(unittest2.TestCase):
 
             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
 





More information about the lldb-commits mailing list