[Lldb-commits] [lldb] r219457 - Enable local llgs debugging on Linux when the use-llgs-for-local setting is enabled.

Todd Fiala todd.fiala at gmail.com
Thu Oct 9 17:09:16 PDT 2014


Author: tfiala
Date: Thu Oct  9 19:09:16 2014
New Revision: 219457

URL: http://llvm.org/viewvc/llvm-project?rev=219457&view=rev
Log:
Enable local llgs debugging on Linux when the use-llgs-for-local setting is enabled.

See http://reviews.llvm.org/D5695 for details.

This change does the following:

Enable lldb-gdbserver (llgs) usage for local-process Linux debugging.
To turn on local llgs debugging support, which is disabled by default, enable this setting:

(lldb) settings set platform.plugin.linux.use-llgs-for-local true
Adds a stream-based Dump() function to FileAction.
Pushes some platform methods that Linux (and FreeBSD) will want to share with MacOSX from PlatformDarwin into PlatformPOSIX.

Reviewed by Greg Clayton.

Modified:
    lldb/trunk/include/lldb/Target/FileAction.h
    lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.cpp
    lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.h
    lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
    lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h
    lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
    lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h
    lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.cpp
    lldb/trunk/source/Target/FileAction.cpp

Modified: lldb/trunk/include/lldb/Target/FileAction.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/FileAction.h?rev=219457&r1=219456&r2=219457&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/FileAction.h (original)
+++ lldb/trunk/include/lldb/Target/FileAction.h Thu Oct  9 19:09:16 2014
@@ -56,6 +56,9 @@ class FileAction
 
     const char *GetPath() const;
 
+    void
+    Dump (Stream &stream) const;
+
   protected:
     Action m_action;    // The action for this file
     int m_fd;           // An existing file descriptor

Modified: lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.cpp?rev=219457&r1=219456&r2=219457&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.cpp Thu Oct  9 19:09:16 2014
@@ -21,16 +21,19 @@
 // C++ Includes
 // Other libraries and framework includes
 // Project includes
-#include "lldb/Core/Error.h"
 #include "lldb/Core/Debugger.h"
+#include "lldb/Core/Error.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleList.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/State.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/Host/FileSpec.h"
 #include "lldb/Host/HostInfo.h"
+#include "lldb/Interpreter/OptionValueProperties.h"
+#include "lldb/Interpreter/Property.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Process.h"
 
@@ -47,18 +50,30 @@ static uint32_t g_initialize_count = 0;
 /// Code to handle the PlatformLinux settings
 //------------------------------------------------------------------
 
-static PropertyDefinition
-g_properties[] =
+namespace
 {
-    { "use-llgs-for-local" , OptionValue::eTypeBoolean, true, false, NULL, NULL, "Control whether the platform uses llgs for local debug sessions." },
-    {  NULL        , OptionValue::eTypeInvalid, false, 0  , NULL, NULL, NULL  }
-};
+    enum
+    {
+        ePropertyUseLlgsForLocal = 0,
+    };
 
-enum {
-    ePropertyUseLlgsForLocal = 0,
-};
+    const PropertyDefinition*
+    GetStaticPropertyDefinitions ()
+    {
+        static PropertyDefinition
+        g_properties[] =
+        {
+            { "use-llgs-for-local" , OptionValue::eTypeBoolean, true, false, NULL, NULL, "Control whether the platform uses llgs for local debug sessions." },
+            {  NULL        , OptionValue::eTypeInvalid, false, 0  , NULL, NULL, NULL  }
+        };
 
+        // Allow environment variable to force using llgs-local.
+        if (getenv("PLATFORM_LINUX_FORCE_LLGS_LOCAL"))
+            g_properties[ePropertyUseLlgsForLocal].default_uint_value = true;
 
+        return g_properties;
+    }
+}
 
 class PlatformLinuxProperties : public Properties
 {
@@ -74,8 +89,8 @@ public:
     PlatformLinuxProperties() :
     Properties ()
     {
-        m_collection_sp.reset (new OptionValueProperties(GetSettingName()));
-        m_collection_sp->Initialize(g_properties);
+        m_collection_sp.reset (new OptionValueProperties(GetSettingName ()));
+        m_collection_sp->Initialize (GetStaticPropertyDefinitions ());
     }
 
     virtual
@@ -87,7 +102,7 @@ public:
     GetUseLlgsForLocal() const
     {
         const uint32_t idx = ePropertyUseLlgsForLocal;
-        return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
+        return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, GetStaticPropertyDefinitions()[idx].default_uint_value != 0);
     }
 };
 
@@ -526,115 +541,249 @@ PlatformLinux::GetSoftwareBreakpointTrap
     return 0;
 }
 
-Error
-PlatformLinux::LaunchProcess (ProcessLaunchInfo &launch_info)
+int32_t
+PlatformLinux::GetResumeCountForLaunchInfo (ProcessLaunchInfo &launch_info)
 {
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
-    Error error;
-    
-    if (IsHost())
-    {
-        if (log)
-            log->Printf ("PlatformLinux::%s() launching process as host", __FUNCTION__);
+    int32_t resume_count = 0;
 
-        if (launch_info.GetFlags().Test (eLaunchFlagLaunchInShell))
-        {
-            const bool is_localhost = true;
-            const bool will_debug = launch_info.GetFlags().Test(eLaunchFlagDebug);
-            const bool first_arg_is_full_shell_command = false;
-            uint32_t num_resumes = GetResumeCountForLaunchInfo (launch_info);
-            if (!launch_info.ConvertArgumentsForLaunchingInShell (error,
-                                                                  is_localhost,
-                                                                  will_debug,
-                                                                  first_arg_is_full_shell_command,
-                                                                  num_resumes))
-                return error;
-        }
-        error = Platform::LaunchProcess (launch_info);
+    // Always resume past the initial stop when we use eLaunchFlagDebug
+    if (launch_info.GetFlags ().Test (eLaunchFlagDebug))
+    {
+        // Resume past the stop for the final exec into the true inferior.
+        ++resume_count;
     }
+
+    // If we're not launching a shell, we're done.
+    const char *shell = launch_info.GetShell();
+    if (shell == NULL)
+        return resume_count;
+
+    // We're in a shell, so for sure we have to resume past the shell exec.
+    ++resume_count;
+
+    // Figure out what shell we're planning on using.
+    const char *shell_name = strrchr (shell, '/');
+    if (shell_name == NULL)
+        shell_name = shell;
     else
+        shell_name++;
+
+    if (strcmp (shell_name, "csh") == 0
+             || strcmp (shell_name, "tcsh") == 0
+             || strcmp (shell_name, "zsh") == 0
+             || strcmp (shell_name, "sh") == 0)
     {
-        if (m_remote_platform_sp)
-        {
-            if (log)
-                log->Printf ("PlatformLinux::%s() attempting to launch remote process", __FUNCTION__);
-            error = m_remote_platform_sp->LaunchProcess (launch_info);
-        }
-        else
-        {
-            if (log)
-                log->Printf ("PlatformLinux::%s() attempted to launch process but is not the host and no remote platform set", __FUNCTION__);
-            error.SetErrorString ("the platform is not currently connected");
-        }
+        // These shells seem to re-exec themselves.  Add another resume.
+        ++resume_count;
     }
-    return error;
+
+    return resume_count;
+}
+
+bool
+PlatformLinux::UseLlgsForLocalDebugging ()
+{
+    PlatformLinuxPropertiesSP properties_sp = GetGlobalProperties ();
+    assert (properties_sp && "global properties shared pointer is null");
+    return properties_sp ? properties_sp->GetUseLlgsForLocal () : false;
 }
 
-// Linux processes can not be launched by spawning and attaching.
 bool
 PlatformLinux::CanDebugProcess ()
 {
-    // If we're the host, launch via normal host setup.
     if (IsHost ())
-        return false;
-
-    // If we're connected, we can debug.
-    return IsConnected ();
+    {
+        // The platform only does local debugging (i.e. uses llgs) when the setting indicates we do that.
+        // Otherwise, we'll use ProcessLinux/ProcessPOSIX to handle with ProcessMonitor.
+        return UseLlgsForLocalDebugging ();
+    }
+    else
+    {
+        // If we're connected, we can debug.
+        return IsConnected ();
+    }
 }
 
+// For local debugging, Linux will override the debug logic to use llgs-launch rather than
+// lldb-launch, llgs-attach.  This differs from current lldb-launch, debugserver-attach
+// approach on MacOSX.
 lldb::ProcessSP
-PlatformLinux::Attach(ProcessAttachInfo &attach_info,
-                      Debugger &debugger,
-                      Target *target,
-                      Listener &listener,
-                      Error &error)
+PlatformLinux::DebugProcess (ProcessLaunchInfo &launch_info,
+                        Debugger &debugger,
+                        Target *target,       // Can be NULL, if NULL create a new target, else use existing one
+                        Listener &listener,
+                        Error &error)
 {
-    lldb::ProcessSP process_sp;
-    if (IsHost())
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
+    if (log)
+        log->Printf ("PlatformLinux::%s entered (target %p)", __FUNCTION__, static_cast<void*>(target));
+
+    // If we're a remote host, use standard behavior from parent class.
+    if (!IsHost ())
+        return PlatformPOSIX::DebugProcess (launch_info, debugger, target, listener, error);
+
+    //
+    // For local debugging, we'll insist on having ProcessGDBRemote create the process.
+    //
+
+    ProcessSP process_sp;
+
+    // Ensure we're using llgs for local debugging.
+    if (!UseLlgsForLocalDebugging ())
     {
-        if (target == NULL)
+        assert (false && "we're trying to debug a local process but platform.plugin.linux.use-llgs-for-local is false, should never get here");
+        error.SetErrorString ("attempted to start gdb-remote-based debugging for local process but platform.plugin.linux.use-llgs-for-local is false");
+        return process_sp;
+    }
+
+    // Make sure we stop at the entry point
+    launch_info.GetFlags ().Set (eLaunchFlagDebug);
+
+    // We always launch the process we are going to debug in a separate process
+    // group, since then we can handle ^C interrupts ourselves w/o having to worry
+    // about the target getting them as well.
+    launch_info.SetLaunchInSeparateProcessGroup(true);
+
+    // Ensure we have a target.
+    if (target == nullptr)
+    {
+        if (log)
+            log->Printf ("PlatformLinux::%s creating new target", __FUNCTION__);
+
+        TargetSP new_target_sp;
+        error = debugger.GetTargetList().CreateTarget (debugger,
+                                                       nullptr,
+                                                       nullptr,
+                                                       false,
+                                                       nullptr,
+                                                       new_target_sp);
+        if (error.Fail ())
         {
-            TargetSP new_target_sp;
-            ArchSpec emptyArchSpec;
+            if (log)
+                log->Printf ("PlatformLinux::%s failed to create new target: %s", __FUNCTION__, error.AsCString ());
+            return process_sp;
+        }
 
-            error = debugger.GetTargetList().CreateTarget (debugger,
-                                                           NULL,
-                                                           emptyArchSpec,
-                                                           false,
-                                                           m_remote_platform_sp,
-                                                           new_target_sp);
-            target = new_target_sp.get();
+        target = new_target_sp.get();
+        if (!target)
+        {
+            error.SetErrorString ("CreateTarget() returned nullptr");
+            if (log)
+                log->Printf ("PlatformLinux::%s failed: %s", __FUNCTION__, error.AsCString ());
+            return process_sp;
         }
-        else
-            error.Clear();
+    }
+    else
+    {
+        if (log)
+            log->Printf ("PlatformLinux::%s using provided target", __FUNCTION__);
+    }
+
+    // Mark target as currently selected target.
+    debugger.GetTargetList().SetSelectedTarget(target);
+
+    // Now create the gdb-remote process.
+    if (log)
+        log->Printf ("PlatformLinux::%s having target create process with gdb-remote plugin", __FUNCTION__);
+    process_sp = target->CreateProcess (listener, "gdb-remote", nullptr);
+
+    if (!process_sp)
+    {
+        error.SetErrorString ("CreateProcess() failed for gdb-remote process");
+        if (log)
+            log->Printf ("PlatformLinux::%s failed: %s", __FUNCTION__, error.AsCString ());
+        return process_sp;
+    }
+    else
+    {
+        if (log)
+            log->Printf ("PlatformLinux::%s successfully created process", __FUNCTION__);
+    }
 
-        if (target && error.Success())
+    // Set the unix signals properly.
+    process_sp->SetUnixSignals (Host::GetUnixSignals ());
+
+    // Adjust launch for a hijacker.
+    ListenerSP listener_sp;
+    if (!launch_info.GetHijackListener ())
+    {
+        if (log)
+            log->Printf ("PlatformLinux::%s setting up hijacker", __FUNCTION__);
+
+        listener_sp.reset (new Listener("lldb.PlatformLinux.DebugProcess.hijack"));
+        launch_info.SetHijackListener (listener_sp);
+        process_sp->HijackProcessEvents (listener_sp.get ());
+    }
+
+    // Log file actions.
+    if (log)
+    {
+        log->Printf ("PlatformLinux::%s launching process with the following file actions:", __FUNCTION__);
+
+        StreamString stream;
+        size_t i = 0;
+        const FileAction *file_action;
+        while ((file_action = launch_info.GetFileActionAtIndex (i++)) != nullptr)
         {
-            debugger.GetTargetList().SetSelectedTarget(target);
+            file_action->Dump (stream);
+            log->PutCString (stream.GetString().c_str ());
+            stream.Clear();
+        }
+    }
 
-            process_sp = target->CreateProcess (listener,
-                                                attach_info.GetProcessPluginName(),
-                                                NULL);
+    // Do the launch.
+    error = process_sp->Launch(launch_info);
+    if (error.Success ())
+    {
+        // Handle the hijacking of process events.
+        if (listener_sp)
+        {
+            const StateType state = process_sp->WaitForProcessToStop (NULL, NULL, false, listener_sp.get());
+            process_sp->RestoreProcessEvents();
 
-            if (process_sp)
-                error = process_sp->Attach (attach_info);
+            if (state == eStateStopped)
+            {
+                if (log)
+                    log->Printf ("PlatformLinux::%s pid %" PRIu64 " state %s\n",
+                                 __FUNCTION__, process_sp->GetID (), StateAsCString (state));
+            }
+            else
+            {
+                if (log)
+                    log->Printf ("PlatformLinux::%s pid %" PRIu64 " state is not stopped - %s\n",
+                                 __FUNCTION__, process_sp->GetID (), StateAsCString (state));
+            }
+        }
+
+        // Hook up process PTY if we have one (which we should for local debugging with llgs).
+        int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
+        if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd)
+        {
+            process_sp->SetSTDIOFileDescriptor(pty_fd);
+            if (log)
+                log->Printf ("PlatformLinux::%s pid %" PRIu64 " hooked up STDIO pty to process", __FUNCTION__, process_sp->GetID ());
+        }
+        else
+        {
+            if (log)
+                log->Printf ("PlatformLinux::%s pid %" PRIu64 " not using process STDIO pty", __FUNCTION__, process_sp->GetID ());
         }
     }
     else
     {
-        if (m_remote_platform_sp)
-            process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, listener, error);
-        else
-            error.SetErrorString ("the platform is not currently connected");
+        if (log)
+            log->Printf ("PlatformLinux::%s process launch failed: %s", __FUNCTION__, error.AsCString ());
+        // FIXME figure out appropriate cleanup here.  Do we delete the target? Do we delete the process?  Does our caller do that?
     }
+
     return process_sp;
 }
 
 void
 PlatformLinux::CalculateTrapHandlerSymbolNames ()
-{   
+{
     m_trap_handlers.push_back (ConstString ("_sigtramp"));
-}   
+}
 
 Error
 PlatformLinux::LaunchNativeProcess (

Modified: lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.h?rev=219457&r1=219456&r2=219457&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.h (original)
+++ lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.h Thu Oct  9 19:09:16 2014
@@ -89,16 +89,19 @@ namespace lldb_private {
         GetSoftwareBreakpointTrapOpcode (Target &target, 
                                          BreakpointSite *bp_site) override;
 
-        lldb_private::Error
-        LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info) override;
-
-        lldb::ProcessSP
-        Attach(ProcessAttachInfo &attach_info, Debugger &debugger,
-               Target *target, Listener &listener, Error &error) override;
+        int32_t
+        GetResumeCountForLaunchInfo (ProcessLaunchInfo &launch_info) override;
 
         bool
         CanDebugProcess () override;
 
+        lldb::ProcessSP
+        DebugProcess (ProcessLaunchInfo &launch_info,
+                      Debugger &debugger,
+                      Target *target,
+                      Listener &listener,
+                      Error &error) override;
+
         void
         CalculateTrapHandlerSymbolNames () override;
 
@@ -113,6 +116,9 @@ namespace lldb_private {
                              lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate,
                              NativeProcessProtocolSP &process_sp) override;
 
+        static bool
+        UseLlgsForLocalDebugging ();
+
     private:
         DISALLOW_COPY_AND_ASSIGN (PlatformLinux);
     };

Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp?rev=219457&r1=219456&r2=219457&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp Thu Oct  9 19:09:16 2014
@@ -672,76 +672,6 @@ PlatformDarwin::FindProcesses (const Pro
     return match_count;    
 }
 
-Error
-PlatformDarwin::LaunchProcess (ProcessLaunchInfo &launch_info)
-{
-    Error error;
-    
-    if (IsHost())
-    {
-        error = Platform::LaunchProcess (launch_info);
-    }
-    else
-    {
-        if (m_remote_platform_sp)
-            error = m_remote_platform_sp->LaunchProcess (launch_info);
-        else
-            error.SetErrorString ("the platform is not currently connected");
-    }
-    return error;
-}
-
-lldb::ProcessSP
-PlatformDarwin::Attach (ProcessAttachInfo &attach_info,
-                        Debugger &debugger,
-                        Target *target,
-                        Listener &listener, 
-                        Error &error)
-{
-    lldb::ProcessSP process_sp;
-    
-    if (IsHost())
-    {
-        if (target == NULL)
-        {
-            TargetSP new_target_sp;
-            
-            error = debugger.GetTargetList().CreateTarget (debugger,
-                                                           NULL,
-                                                           NULL, 
-                                                           false,
-                                                           NULL,
-                                                           new_target_sp);
-            target = new_target_sp.get();
-        }
-        else
-            error.Clear();
-    
-        if (target && error.Success())
-        {
-            debugger.GetTargetList().SetSelectedTarget(target);
-
-            process_sp = target->CreateProcess (listener, attach_info.GetProcessPluginName(), NULL);
-            
-            if (process_sp)
-            {
-                ListenerSP listener_sp (new Listener("lldb.PlatformDarwin.attach.hijack"));
-                attach_info.SetHijackListener(listener_sp);
-                process_sp->HijackProcessEvents(listener_sp.get());
-                error = process_sp->Attach (attach_info);
-            }
-        }
-    }
-    else
-    {
-        if (m_remote_platform_sp)
-            process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, listener, error);
-        else
-            error.SetErrorString ("the platform is not currently connected");
-    }
-    return process_sp;
-}
-
 bool
 PlatformDarwin::ModuleIsExcludedForNonModuleSpecificSearches (lldb_private::Target &target, const lldb::ModuleSP &module_sp)
 {

Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h?rev=219457&r1=219456&r2=219457&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h Thu Oct  9 19:09:16 2014
@@ -65,16 +65,6 @@ public:
     FindProcesses (const lldb_private::ProcessInstanceInfoMatch &match_info,
                    lldb_private::ProcessInstanceInfoList &process_infos);
     
-    virtual lldb_private::Error
-    LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info);
-
-    virtual lldb::ProcessSP
-    Attach (lldb_private::ProcessAttachInfo &attach_info,
-            lldb_private::Debugger &debugger,
-            lldb_private::Target *target,       // Can be NULL, if NULL create a new target, else use existing one
-            lldb_private::Listener &listener, 
-            lldb_private::Error &error);
-
     virtual bool
     ModuleIsExcludedForNonModuleSpecificSearches (lldb_private::Target &target, const lldb::ModuleSP &module_sp);
     

Modified: lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp?rev=219457&r1=219456&r2=219457&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp Thu Oct  9 19:09:16 2014
@@ -15,7 +15,9 @@
 // Project includes
 
 #include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Debugger.h"
 #include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/Host/File.h"
 #include "lldb/Host/FileCache.h"
@@ -769,6 +771,94 @@ PlatformPOSIX::DisconnectRemote ()
     return error;
 }
 
+Error
+PlatformPOSIX::LaunchProcess (ProcessLaunchInfo &launch_info)
+{
+    Error error;
+
+    if (IsHost())
+    {
+        error = Platform::LaunchProcess (launch_info);
+    }
+    else
+    {
+        if (m_remote_platform_sp)
+            error = m_remote_platform_sp->LaunchProcess (launch_info);
+        else
+            error.SetErrorString ("the platform is not currently connected");
+    }
+    return error;
+}
+
+lldb::ProcessSP
+PlatformPOSIX::Attach (ProcessAttachInfo &attach_info,
+                       Debugger &debugger,
+                       Target *target,
+                       Listener &listener,
+                       Error &error)
+{
+    lldb::ProcessSP process_sp;
+    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+
+    if (IsHost())
+    {
+        if (target == NULL)
+        {
+            TargetSP new_target_sp;
+
+            error = debugger.GetTargetList().CreateTarget (debugger,
+                                                           NULL,
+                                                           NULL,
+                                                           false,
+                                                           NULL,
+                                                           new_target_sp);
+            target = new_target_sp.get();
+            if (log)
+                log->Printf ("PlatformPOSIX::%s created new target", __FUNCTION__);
+        }
+        else
+        {
+            error.Clear();
+            if (log)
+                log->Printf ("PlatformPOSIX::%s target already existed, setting target", __FUNCTION__);
+        }
+
+        if (target && error.Success())
+        {
+            debugger.GetTargetList().SetSelectedTarget(target);
+            if (log)
+            {
+                ModuleSP exe_module_sp = target->GetExecutableModule ();
+                log->Printf ("PlatformPOSIX::%s set selected target to %p %s", __FUNCTION__,
+                             target,
+                             exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str () : "<null>" );
+            }
+
+
+            process_sp = target->CreateProcess (listener, attach_info.GetProcessPluginName(), NULL);
+
+            if (process_sp)
+            {
+                // Set UnixSignals appropriately.
+                process_sp->SetUnixSignals (Host::GetUnixSignals ());
+
+                ListenerSP listener_sp (new Listener("lldb.PlatformPOSIX.attach.hijack"));
+                attach_info.SetHijackListener(listener_sp);
+                process_sp->HijackProcessEvents(listener_sp.get());
+                error = process_sp->Attach (attach_info);
+            }
+        }
+    }
+    else
+    {
+        if (m_remote_platform_sp)
+            process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, listener, error);
+        else
+            error.SetErrorString ("the platform is not currently connected");
+    }
+    return process_sp;
+}
+
 lldb::ProcessSP
 PlatformPOSIX::DebugProcess (ProcessLaunchInfo &launch_info,
                               Debugger &debugger,

Modified: lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h?rev=219457&r1=219456&r2=219457&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h (original)
+++ lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h Thu Oct  9 19:09:16 2014
@@ -130,6 +130,16 @@ public:
     virtual lldb_private::Error
     Unlink (const char *path);
 
+    lldb_private::Error
+    LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info) override;
+
+    lldb::ProcessSP
+    Attach (lldb_private::ProcessAttachInfo &attach_info,
+            lldb_private::Debugger &debugger,
+            lldb_private::Target *target,       // Can be NULL, if NULL create a new target, else use existing one
+            lldb_private::Listener &listener,
+            lldb_private::Error &error) override;
+
     lldb::ProcessSP
     DebugProcess (lldb_private::ProcessLaunchInfo &launch_info,
                   lldb_private::Debugger &debugger,

Modified: lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.cpp?rev=219457&r1=219456&r2=219457&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.cpp Thu Oct  9 19:09:16 2014
@@ -20,6 +20,7 @@
 #include "lldb/Target/Target.h"
 
 #include "ProcessLinux.h"
+#include "Plugins/Platform/Linux/PlatformLinux.h"
 #include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
 #include "Plugins/Process/Utility/InferiorCallPOSIX.h"
 #include "Plugins/Process/Utility/LinuxSignals.h"
@@ -229,6 +230,11 @@ ProcessLinux::CanDebug(Target &target, b
     if (m_core_file)
         return false;
 
+    // If we're using llgs for local debugging, we must not say that this process
+    // is used for debugging.
+    if (PlatformLinux::UseLlgsForLocalDebugging ())
+        return false;
+
     return ProcessPOSIX::CanDebug(target, plugin_specified_by_name);
 }
 

Modified: lldb/trunk/source/Target/FileAction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/FileAction.cpp?rev=219457&r1=219456&r2=219457&view=diff
==============================================================================
--- lldb/trunk/source/Target/FileAction.cpp (original)
+++ lldb/trunk/source/Target/FileAction.cpp Thu Oct  9 19:09:16 2014
@@ -13,6 +13,7 @@
 #include "lldb/Host/Windows/win32.h" // For O_NOCTTY
 #endif
 
+#include "lldb/Core/Stream.h"
 #include "lldb/Target/FileAction.h"
 
 using namespace lldb_private;
@@ -93,3 +94,24 @@ FileAction::Duplicate(int fd, int dup_fd
     }
     return m_fd >= 0;
 }
+
+void
+FileAction::Dump(Stream &stream) const
+{
+    stream.PutCString("file action: ");
+    switch (m_action)
+    {
+        case eFileActionClose:
+            stream.Printf("close fd %d", m_fd);
+            break;
+        case eFileActionDuplicate:
+            stream.Printf("duplicate fd %d to %d", m_fd, m_arg);
+            break;
+        case eFileActionNone:
+            stream.PutCString("no action");
+            break;
+        case eFileActionOpen:
+            stream.Printf("open fd %d with '%s', OFLAGS = 0x%x", m_fd, m_path.c_str(), m_arg);
+            break;
+    }
+}





More information about the lldb-commits mailing list