[Lldb-commits] [lldb] r250735 - Allow LLDB.framework to locate debugserver even when it doesn't exist in the LLDB.framework.

Greg Clayton via lldb-commits lldb-commits at lists.llvm.org
Mon Oct 19 13:44:01 PDT 2015


Author: gclayton
Date: Mon Oct 19 15:44:01 2015
New Revision: 250735

URL: http://llvm.org/viewvc/llvm-project?rev=250735&view=rev
Log:
Allow LLDB.framework to locate debugserver even when it doesn't exist in the LLDB.framework.

This allows open source MacOSX clients to not have to build debugserver and the current LLDB can find debugserver inside the selected Xcode.app on your system.

<rdar://problem/23167253>


Modified:
    lldb/trunk/include/lldb/Target/Platform.h
    lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
    lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp

Modified: lldb/trunk/include/lldb/Target/Platform.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Platform.h?rev=250735&r1=250734&r2=250735&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Platform.h (original)
+++ lldb/trunk/include/lldb/Target/Platform.h Mon Oct 19 15:44:01 2015
@@ -947,6 +947,29 @@ class ModuleCache;
         virtual const std::vector<ConstString> &
         GetTrapHandlerSymbolNames ();
 
+
+        //------------------------------------------------------------------
+        /// Find a support executable that may not live within in the
+        /// standard locations related to LLDB.
+        ///
+        /// Executable might exist within the Platform SDK directories, or
+        /// in standard tool directories within the current IDE that is
+        /// running LLDB.
+        ///
+        /// @param[in] basename
+        ///     The basename of the executable to locate in the current
+        ///     platform.
+        ///
+        /// @return
+        ///     A FileSpec pointing to the executable on disk, or an invalid
+        ///     FileSpec if the executable cannot be found.
+        //------------------------------------------------------------------
+        virtual FileSpec
+        LocateExecutable (const char *basename)
+        {
+            return FileSpec();
+        }
+
     protected:
         bool m_is_host;
         // Set to true when we are able to actually set the OS version while 

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=250735&r1=250734&r2=250735&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp Mon Oct 19 15:44:01 2015
@@ -1211,11 +1211,13 @@ static const char *const sdk_strings[] =
 static FileSpec
 GetXcodeContentsPath ()
 {
-    const char substr[] = ".app/Contents/";
-    
-    // First, try based on the current shlib's location
+    static FileSpec g_xcode_filespec;
+    static std::once_flag g_once_flag;
+    std::call_once(g_once_flag, []() {
+
+        const char substr[] = ".app/Contents/";
     
-    {
+        // First, try based on the current shlib's location
         FileSpec fspec;
         
         if (HostInfo::GetLLDBPath (lldb::ePathTypeLLDBShlibDir, fspec))
@@ -1225,42 +1227,42 @@ GetXcodeContentsPath ()
             if (pos != std::string::npos)
             {
                 path_to_shlib.erase(pos + strlen(substr));
-                return FileSpec(path_to_shlib.c_str(), false);
+                g_xcode_filespec = FileSpec(path_to_shlib.c_str(), false);
             }
         }
-    }
-    
-    // Fall back to using xcrun
-    
-    {
-        int status = 0;
-        int signo = 0;
-        std::string output;
-        const char *command = "xcrun -sdk macosx --show-sdk-path";
-        lldb_private::Error error = Host::RunShellCommand (command,   // shell command to run
-                                                           NULL,      // current working directory
-                                                           &status,   // Put the exit status of the process in here
-                                                           &signo,    // Put the signal that caused the process to exit in here
-                                                           &output,   // Get the output from the command and place it in this string
-                                                           3);        // Timeout in seconds to wait for shell program to finish
-        if (status == 0 && !output.empty())
+
+        // Fall back to using xcrun
+        if (!g_xcode_filespec)
         {
-            size_t first_non_newline = output.find_last_not_of("\r\n");
-            if (first_non_newline != std::string::npos)
+            int status = 0;
+            int signo = 0;
+            std::string output;
+            const char *command = "xcrun -sdk macosx --show-sdk-path";
+            lldb_private::Error error = Host::RunShellCommand (command,   // shell command to run
+                                                               NULL,      // current working directory
+                                                               &status,   // Put the exit status of the process in here
+                                                               &signo,    // Put the signal that caused the process to exit in here
+                                                               &output,   // Get the output from the command and place it in this string
+                                                               3);        // Timeout in seconds to wait for shell program to finish
+            if (status == 0 && !output.empty())
             {
-                output.erase(first_non_newline+1);
-            }
-            
-            size_t pos = output.rfind(substr);
-            if (pos != std::string::npos)
-            {
-                output.erase(pos + strlen(substr));
-                return FileSpec(output.c_str(), false);
+                size_t first_non_newline = output.find_last_not_of("\r\n");
+                if (first_non_newline != std::string::npos)
+                {
+                    output.erase(first_non_newline+1);
+                }
+                
+                size_t pos = output.rfind(substr);
+                if (pos != std::string::npos)
+                {
+                    output.erase(pos + strlen(substr));
+                    g_xcode_filespec = FileSpec(output.c_str(), false);
+                }
             }
         }
-    }
+    });
     
-    return FileSpec();
+    return g_xcode_filespec;
 }
 
 bool
@@ -1543,3 +1545,59 @@ PlatformDarwin::GetFullNameForDylib (Con
     return ConstString(stream.GetData());
 }
 
+
+lldb_private::FileSpec
+PlatformDarwin::LocateExecutable (const char *basename)
+{
+    // A collection of SBFileSpec whose SBFileSpec.m_directory members are filled in with
+    // any executable directories that should be searched.
+    static std::vector<FileSpec> g_executable_dirs;
+
+    // Find the global list of directories that we will search for
+    // executables once so we don't keep doing the work over and over.
+    static std::once_flag g_once_flag;
+    std::call_once(g_once_flag,  []() {
+
+        // When locating executables, trust the DEVELOPER_DIR first if it is set
+        FileSpec xcode_contents_dir;
+        const char *developer_dir_env_var = getenv("DEVELOPER_DIR");
+        if (developer_dir_env_var && developer_dir_env_var[0])
+        {
+            xcode_contents_dir = FileSpec(developer_dir_env_var, true);
+            if (xcode_contents_dir.Exists())
+                xcode_contents_dir.RemoveLastPathComponent();
+        }
+        if (!xcode_contents_dir)
+        {
+            xcode_contents_dir = GetXcodeContentsPath();
+            if (!xcode_contents_dir.Exists())
+                xcode_contents_dir.Clear();
+        }
+        if (xcode_contents_dir)
+        {
+            FileSpec xcode_lldb_resources = xcode_contents_dir;
+            xcode_lldb_resources.AppendPathComponent("SharedFrameworks");
+            xcode_lldb_resources.AppendPathComponent("LLDB.framework");
+            xcode_lldb_resources.AppendPathComponent("Resources");
+            if (xcode_lldb_resources.Exists())
+            {
+                FileSpec dir;
+                dir.GetDirectory().SetCString(xcode_lldb_resources.GetPath().c_str());
+                g_executable_dirs.push_back(dir);
+            }
+        }
+    });
+
+    // Now search the global list of executable directories for the executable we
+    // are looking for
+    for (const auto &executable_dir : g_executable_dirs)
+    {
+        FileSpec executable_file;
+        executable_file.GetDirectory() = executable_dir.GetDirectory();
+        executable_file.GetFilename().SetCString(basename);
+        if (executable_file.Exists())
+            return executable_file;
+    }
+
+    return FileSpec();
+}

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=250735&r1=250734&r2=250735&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.h Mon Oct 19 15:44:01 2015
@@ -88,6 +88,9 @@ public:
     lldb_private::ConstString
     GetFullNameForDylib (lldb_private::ConstString basename) override;
 
+    lldb_private::FileSpec
+    LocateExecutable (const char *basename) override;
+
 protected:
 
     void

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp?rev=250735&r1=250734&r2=250735&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Mon Oct 19 15:44:01 2015
@@ -30,6 +30,7 @@
 #include "lldb/Host/StringConvert.h"
 #include "lldb/Host/ThreadLauncher.h"
 #include "lldb/Host/TimeValue.h"
+#include "lldb/Target/Platform.h"
 #include "lldb/Target/Process.h"
 #include "llvm/ADT/SmallString.h"
 
@@ -1113,6 +1114,7 @@ GDBRemoteCommunication::ListenThread (ll
 Error
 GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
                                                  uint16_t in_port,
+                                                 Platform *platform,
                                                  ProcessLaunchInfo &launch_info,
                                                  uint16_t &out_port)
 {
@@ -1157,11 +1159,20 @@ GDBRemoteCommunication::StartDebugserver
             }
             else
             {
-                if (log)
-                    log->Printf ("GDBRemoteCommunication::%s() could not find gdb-remote stub exe '%s'", __FUNCTION__, debugserver_file_spec.GetPath ().c_str ());
-
+                debugserver_file_spec = platform->LocateExecutable(DEBUGSERVER_BASENAME);
+                if (debugserver_file_spec)
+                {
+                    // Platform::LocateExecutable() wouldn't return a path if it doesn't exist
+                    debugserver_exists = true;
+                }
+                else
+                {
+                    if (log)
+                        log->Printf ("GDBRemoteCommunication::%s() could not find gdb-remote stub exe '%s'", __FUNCTION__, debugserver_file_spec.GetPath ().c_str ());
+                }
+                // Don't cache the platform specific GDB server binary as it could change
+                // from platform to platform
                 g_debugserver_file_spec.Clear();
-                debugserver_file_spec.Clear();
             }
         }
     }

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h?rev=250735&r1=250734&r2=250735&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h Mon Oct 19 15:44:01 2015
@@ -169,6 +169,7 @@ public:
     Error
     StartDebugserverProcess (const char *hostname,
                              uint16_t in_port, // If set to zero, then out_port will contain the bound port on exit
+                             Platform *platform, // If non NULL, then check with the platform for the GDB server binary if it can't be located
                              ProcessLaunchInfo &launch_info,
                              uint16_t &out_port);
 

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp?rev=250735&r1=250734&r2=250735&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp Mon Oct 19 15:44:01 2015
@@ -138,11 +138,11 @@ GDBRemoteCommunicationServerPlatform::Ha
     bool ok = UriParser::Parse(GetConnection()->GetURI().c_str(), platform_scheme, platform_ip, platform_port, platform_path);
     UNUSED_IF_ASSERT_DISABLED(ok);
     assert(ok);
-    Error error = StartDebugserverProcess (
-                                     platform_ip.c_str(),
-                                     port,
-                                     debugserver_launch_info,
-                                     port);
+    Error error = StartDebugserverProcess (platform_ip.c_str(),
+                                           port,
+                                           nullptr,
+                                           debugserver_launch_info,
+                                           port);
 
     lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID();
 

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=250735&r1=250734&r2=250735&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Mon Oct 19 15:44:01 2015
@@ -3568,6 +3568,7 @@ ProcessGDBRemote::LaunchAndConnectToDebu
 
         error = m_gdb_comm.StartDebugserverProcess (hostname,
                                                     port,
+                                                    GetTarget().GetPlatform().get(),
                                                     debugserver_launch_info,
                                                     port);
 




More information about the lldb-commits mailing list