Index: include/lldb/Host/Host.h =================================================================== --- include/lldb/Host/Host.h +++ include/lldb/Host/Host.h @@ -341,28 +341,6 @@ ResolveExecutableInBundle (FileSpec &file); //------------------------------------------------------------------ - /// Find a resource files that are related to LLDB. - /// - /// Operating systems have different ways of storing shared - /// libraries and related resources. This function abstracts the - /// access to these paths. - /// - /// @param[in] path_type - /// The type of LLDB resource path you are looking for. If the - /// enumeration ends with "Dir", then only the \a file_spec's - /// directory member gets filled in. - /// - /// @param[in] file_spec - /// A file spec that gets filled in with the appropriate path. - /// - /// @return - /// \b true if \a resource_path was resolved, \a false otherwise. - //------------------------------------------------------------------ - static bool - GetLLDBPath (lldb::PathType path_type, - FileSpec &file_spec); - - //------------------------------------------------------------------ /// Set a string that can be displayed if host application crashes. /// /// Some operating systems have the ability to print a description Index: include/lldb/Host/HostInfoBase.h =================================================================== --- include/lldb/Host/HostInfoBase.h +++ include/lldb/Host/HostInfoBase.h @@ -11,6 +11,8 @@ #define lldb_Host_HostInfoBase_h_ #include "lldb/Core/ArchSpec.h" +#include "lldb/Host/FileSpec.h" +#include "lldb/lldb-enumerations.h" #include "llvm/ADT/StringRef.h" @@ -21,6 +23,8 @@ namespace lldb_private { +class FileSpec; + class HostInfoBase { private: @@ -78,7 +82,34 @@ static const ArchSpec &GetArchitecture(ArchitectureKind arch_kind = eArchKindDefault); + //------------------------------------------------------------------ + /// Find a resource files that are related to LLDB. + /// + /// Operating systems have different ways of storing shared + /// libraries and related resources. This function abstracts the + /// access to these paths. + /// + /// @param[in] path_type + /// The type of LLDB resource path you are looking for. If the + /// enumeration ends with "Dir", then only the \a file_spec's + /// directory member gets filled in. + /// + /// @param[in] file_spec + /// A file spec that gets filled in with the appropriate path. + /// + /// @return + /// \b true if \a resource_path was resolved, \a false otherwise. + //------------------------------------------------------------------ + static bool GetLLDBPath(lldb::PathType type, FileSpec &file_spec); + protected: + static bool ComputeSharedLibraryDirectory(FileSpec &file_spec); + static bool ComputeSupportExeDirectory(FileSpec &file_spec); + static bool ComputeTempFileDirectory(FileSpec &file_spec); + static bool ComputeHeaderDirectory(FileSpec &file_spec); + static bool ComputeSystemPluginsDirectory(FileSpec &file_spec); + static bool ComputeUserPluginsDirectory(FileSpec &file_spec); + static void ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64); static uint32_t m_number_cpus; @@ -88,6 +119,14 @@ static ArchSpec m_host_arch_32; static ArchSpec m_host_arch_64; + + static FileSpec m_lldb_so_dir; + static FileSpec m_lldb_support_exe_dir; + static FileSpec m_lldb_headers_dir; + static FileSpec m_lldb_python_dir; + static FileSpec m_lldb_system_plugin_dir; + static FileSpec m_lldb_user_plugin_dir; + static FileSpec m_lldb_tmp_dir; }; } Index: include/lldb/Host/linux/HostInfoLinux.h =================================================================== --- include/lldb/Host/linux/HostInfoLinux.h +++ include/lldb/Host/linux/HostInfoLinux.h @@ -32,6 +32,8 @@ static llvm::StringRef GetDistributionId(); protected: + static bool ComputeSystemPluginsDirectory(FileSpec &file_spec); + static bool ComputeUserPluginsDirectory(FileSpec &file_spec); static void ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64); static std::string m_distribution_id; Index: include/lldb/Host/macosx/HostInfoMacOSX.h =================================================================== --- include/lldb/Host/macosx/HostInfoMacOSX.h +++ include/lldb/Host/macosx/HostInfoMacOSX.h @@ -32,7 +32,12 @@ static bool GetOSKernelDescription(std::string &s); protected: + static bool ComputeSupportExeDirectory(FileSpec &file_spec); static void ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64); + static bool ComputeHeaderDirectory(FileSpec &file_spec); + static bool ComputePythonDirectory(FileSpec &file_spec); + static bool ComputeSystemPluginsDirectory(FileSpec &file_spec); + static bool ComputeUserPluginsDirectory(FileSpec &file_spec); }; } Index: include/lldb/Host/posix/HostInfoPosix.h =================================================================== --- include/lldb/Host/posix/HostInfoPosix.h +++ include/lldb/Host/posix/HostInfoPosix.h @@ -17,9 +17,16 @@ class HostInfoPosix : public HostInfoBase { + friend class HostInfoBase; + public: static size_t GetPageSize(); static bool GetHostname(std::string &s); + + protected: + static bool ComputeSupportExeDirectory(FileSpec &file_spec); + static bool ComputeHeaderDirectory(FileSpec &file_spec); + static bool ComputePythonDirectory(FileSpec &file_spec); }; } Index: include/lldb/Host/windows/HostInfoWindows.h =================================================================== --- include/lldb/Host/windows/HostInfoWindows.h +++ include/lldb/Host/windows/HostInfoWindows.h @@ -17,6 +17,8 @@ class HostInfoWindows : public HostInfoBase { + friend class HostInfoBase; + private: // Static class, unconstructable. HostInfoWindows(); @@ -29,6 +31,9 @@ static bool GetOSBuildString(std::string &s); static bool GetOSKernelDescription(std::string &s); static bool GetHostname(std::string &s); + + protected: + static bool ComputePythonDirectory(FileSpec &file_spec); }; } Index: source/API/SBHostOS.cpp =================================================================== --- source/API/SBHostOS.cpp +++ source/API/SBHostOS.cpp @@ -12,6 +12,7 @@ #include "lldb/Host/FileSpec.h" #include "lldb/Core/Log.h" #include "lldb/Host/Host.h" +#include "lldb/Host/HostInfo.h" using namespace lldb; using namespace lldb_private; @@ -31,7 +32,7 @@ { SBFileSpec sb_lldb_python_filespec; FileSpec lldb_python_spec; - if (Host::GetLLDBPath (ePathTypePythonDir, lldb_python_spec)) + if (HostInfo::GetLLDBPath(ePathTypePythonDir, lldb_python_spec)) { sb_lldb_python_filespec.SetFileSpec (lldb_python_spec); } @@ -44,7 +45,7 @@ { SBFileSpec sb_fspec; FileSpec fspec; - if (Host::GetLLDBPath (path_type, fspec)) + if (HostInfo::GetLLDBPath(path_type, fspec)) sb_fspec.SetFileSpec (fspec); return sb_fspec; } Index: source/Core/Debugger.cpp =================================================================== --- source/Core/Debugger.cpp +++ source/Core/Debugger.cpp @@ -35,6 +35,7 @@ #include "lldb/DataFormatters/FormatManager.h" #include "lldb/DataFormatters/TypeSummary.h" #include "lldb/Host/DynamicLibrary.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Host/Terminal.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/OptionValueSInt64.h" @@ -492,7 +493,7 @@ const bool find_files = true; const bool find_other = true; char dir_path[PATH_MAX]; - if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec)) + if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec)) { if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) { @@ -504,8 +505,8 @@ this); } } - - if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec)) + + if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec)) { if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) { Index: source/Core/PluginManager.cpp =================================================================== --- source/Core/PluginManager.cpp +++ source/Core/PluginManager.cpp @@ -20,6 +20,7 @@ #include "lldb/Core/Error.h" #include "lldb/Host/FileSpec.h" #include "lldb/Host/Host.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Host/Mutex.h" #include "lldb/Interpreter/OptionValueProperties.h" @@ -185,7 +186,7 @@ const bool find_files = true; const bool find_other = true; char dir_path[PATH_MAX]; - if (Host::GetLLDBPath (ePathTypeLLDBSystemPlugins, dir_spec)) + if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec)) { if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) { @@ -198,7 +199,7 @@ } } - if (Host::GetLLDBPath (ePathTypeLLDBUserPlugins, dir_spec)) + if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec)) { if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) { Index: source/Expression/ClangExpressionParser.cpp =================================================================== --- source/Expression/ClangExpressionParser.cpp +++ source/Expression/ClangExpressionParser.cpp @@ -26,6 +26,7 @@ #include "lldb/Expression/IRDynamicChecks.h" #include "lldb/Expression/IRInterpreter.h" #include "lldb/Host/File.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/ObjCLanguageRuntime.h" @@ -309,7 +310,7 @@ std::string temp_source_path; FileSpec tmpdir_file_spec; - if (Host::GetLLDBPath (lldb::ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) + if (HostInfo::GetLLDBPath(lldb::ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) { tmpdir_file_spec.GetFilename().SetCString("expr.XXXXXX"); temp_source_path = std::move(tmpdir_file_spec.GetPath()); Index: source/Host/common/Host.cpp =================================================================== --- source/Host/common/Host.cpp +++ source/Host/common/Host.cpp @@ -865,346 +865,6 @@ #endif - -static void CleanupProcessSpecificLLDBTempDir () -{ - // Get the process specific LLDB temporary directory and delete it. - FileSpec tmpdir_file_spec; - if (Host::GetLLDBPath (ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) - { - // Remove the LLDB temporary directory if we have one. Set "recurse" to - // true to all files that were created for the LLDB process can be cleaned up. - const bool recurse = true; - FileSystem::DeleteDirectory(tmpdir_file_spec.GetDirectory().GetCString(), recurse); - } -} - -bool -Host::GetLLDBPath (PathType path_type, FileSpec &file_spec) -{ - // To get paths related to LLDB we get the path to the executable that - // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB", - // on linux this is assumed to be the "lldb" main executable. If LLDB on - // linux is actually in a shared library (liblldb.so) then this function will - // need to be modified to "do the right thing". - Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST); - - switch (path_type) - { - case ePathTypeLLDBShlibDir: - { - static ConstString g_lldb_so_dir; - if (!g_lldb_so_dir) - { - FileSpec lldb_file_spec(Host::GetModuleFileSpecForHostAddress( - reinterpret_cast(reinterpret_cast(Host::GetLLDBPath)))); - g_lldb_so_dir = lldb_file_spec.GetDirectory(); - if (log) - log->Printf("Host::GetLLDBPath(ePathTypeLLDBShlibDir) => '%s'", g_lldb_so_dir.GetCString()); - } - file_spec.GetDirectory() = g_lldb_so_dir; - return (bool)file_spec.GetDirectory(); - } - break; - - case ePathTypeSupportExecutableDir: - { - static ConstString g_lldb_support_exe_dir; - if (!g_lldb_support_exe_dir) - { - FileSpec lldb_file_spec; - if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) - { - char raw_path[PATH_MAX]; - lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); - -#if defined (__APPLE__) - char *framework_pos = ::strstr (raw_path, "LLDB.framework"); - if (framework_pos) - { - framework_pos += strlen("LLDB.framework"); -#if defined (__arm__) || defined (__arm64__) || defined (__aarch64__) - // Shallow bundle - *framework_pos = '\0'; -#else - // Normal bundle - ::strncpy (framework_pos, "/Resources", PATH_MAX - (framework_pos - raw_path)); -#endif - } -#elif defined (__linux__) || defined (__FreeBSD__) || defined (__NetBSD__) - // Linux/*BSD will attempt to replace a */lib with */bin as the base directory for - // helper exe programs. This will fail if the /lib and /bin directories are rooted in entirely - // different trees. - if (log) - log->Printf ("Host::%s() attempting to derive the bin path (ePathTypeSupportExecutableDir) from this path: %s", __FUNCTION__, raw_path); - char *lib_pos = ::strstr (raw_path, "/lib"); - if (lib_pos != nullptr) - { - // First terminate the raw path at the start of lib. - *lib_pos = '\0'; - - // Now write in bin in place of lib. - ::strncpy (lib_pos, "/bin", PATH_MAX - (lib_pos - raw_path)); - - if (log) - log->Printf ("Host::%s() derived the bin path as: %s", __FUNCTION__, raw_path); - } - else - { - if (log) - log->Printf ("Host::%s() failed to find /lib/liblldb within the shared lib path, bailing on bin path construction", __FUNCTION__); - } -#endif // #if defined (__APPLE__) - llvm::SmallString<64> resolved_path(raw_path); - FileSpec::Resolve (resolved_path); - g_lldb_support_exe_dir.SetCString(resolved_path.c_str()); - } - if (log) - log->Printf("Host::GetLLDBPath(ePathTypeSupportExecutableDir) => '%s'", g_lldb_support_exe_dir.GetCString()); - } - file_spec.GetDirectory() = g_lldb_support_exe_dir; - return (bool)file_spec.GetDirectory(); - } - break; - - case ePathTypeHeaderDir: - { - static ConstString g_lldb_headers_dir; - if (!g_lldb_headers_dir) - { -#if defined (__APPLE__) - FileSpec lldb_file_spec; - if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) - { - char raw_path[PATH_MAX]; - lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); - - char *framework_pos = ::strstr (raw_path, "LLDB.framework"); - if (framework_pos) - { - framework_pos += strlen("LLDB.framework"); - ::strncpy (framework_pos, "/Headers", PATH_MAX - (framework_pos - raw_path)); - } - llvm::SmallString<64> resolved_path(raw_path); - FileSpec::Resolve (resolved_path); - g_lldb_headers_dir.SetCString(resolved_path.c_str()); - } -#else - // TODO: Anyone know how we can determine this for linux? Other systems?? - g_lldb_headers_dir.SetCString ("/opt/local/include/lldb"); -#endif - if (log) - log->Printf("Host::GetLLDBPath(ePathTypeHeaderDir) => '%s'", g_lldb_headers_dir.GetCString()); - } - file_spec.GetDirectory() = g_lldb_headers_dir; - return (bool)file_spec.GetDirectory(); - } - break; - -#ifdef LLDB_DISABLE_PYTHON - case ePathTypePythonDir: - return false; -#else - case ePathTypePythonDir: - { - static ConstString g_lldb_python_dir; - if (!g_lldb_python_dir) - { - FileSpec lldb_file_spec; - if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) - { - char raw_path[PATH_MAX]; -#if defined(_WIN32) - lldb_file_spec.AppendPathComponent("../lib/site-packages"); - lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); -#else - lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); - -#if defined (__APPLE__) - char *framework_pos = ::strstr (raw_path, "LLDB.framework"); - if (framework_pos) - { - framework_pos += strlen("LLDB.framework"); - ::strncpy (framework_pos, "/Resources/Python", PATH_MAX - (framework_pos - raw_path)); - } - else - { -#endif - llvm::SmallString<256> python_version_dir; - llvm::raw_svector_ostream os(python_version_dir); - os << "/python" << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION << "/site-packages"; - os.flush(); - - // We may get our string truncated. Should we protect - // this with an assert? - - ::strncat(raw_path, python_version_dir.c_str(), - sizeof(raw_path) - strlen(raw_path) - 1); -#endif -#if defined (__APPLE__) - } -#endif - llvm::SmallString<64> resolved_path(raw_path); - FileSpec::Resolve (resolved_path); - g_lldb_python_dir.SetCString(resolved_path.c_str()); - } - - if (log) - log->Printf("Host::GetLLDBPath(ePathTypePythonDir) => '%s'", g_lldb_python_dir.GetCString()); - - } - file_spec.GetDirectory() = g_lldb_python_dir; - return (bool)file_spec.GetDirectory(); - } - break; -#endif - - case ePathTypeLLDBSystemPlugins: // System plug-ins directory - { -#if defined (__APPLE__) || defined(__linux__) - static ConstString g_lldb_system_plugin_dir; - static bool g_lldb_system_plugin_dir_located = false; - if (!g_lldb_system_plugin_dir_located) - { - g_lldb_system_plugin_dir_located = true; -#if defined (__APPLE__) - FileSpec lldb_file_spec; - if (GetLLDBPath (ePathTypeLLDBShlibDir, lldb_file_spec)) - { - char raw_path[PATH_MAX]; - lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); - - char *framework_pos = ::strstr (raw_path, "LLDB.framework"); - if (framework_pos) - { - framework_pos += strlen("LLDB.framework"); - ::strncpy (framework_pos, "/Resources/PlugIns", PATH_MAX - (framework_pos - raw_path)); - llvm::SmallString<64> resolved_path(raw_path); - FileSpec::Resolve (resolved_path); - g_lldb_system_plugin_dir.SetCString(resolved_path.c_str()); - } - return false; - } -#elif defined (__linux__) - FileSpec lldb_file_spec("/usr/lib/lldb", true); - if (lldb_file_spec.Exists()) - { - g_lldb_system_plugin_dir.SetCString(lldb_file_spec.GetPath().c_str()); - } -#endif // __APPLE__ || __linux__ - - if (log) - log->Printf("Host::GetLLDBPath(ePathTypeLLDBSystemPlugins) => '%s'", g_lldb_system_plugin_dir.GetCString()); - - } - - if (g_lldb_system_plugin_dir) - { - file_spec.GetDirectory() = g_lldb_system_plugin_dir; - return true; - } -#else - // TODO: where would system LLDB plug-ins be located on other systems? - return false; -#endif - } - break; - - case ePathTypeLLDBUserPlugins: // User plug-ins directory - { -#if defined (__APPLE__) - static ConstString g_lldb_user_plugin_dir; - if (!g_lldb_user_plugin_dir) - { - llvm::SmallString<64> user_plugin_path("~/Library/Application Support/LLDB/PlugIns"); - FileSpec::Resolve (user_plugin_path); - if (user_plugin_path.size()) - { - g_lldb_user_plugin_dir.SetCString(user_plugin_path.c_str()); - } - } - file_spec.GetDirectory() = g_lldb_user_plugin_dir; - return (bool)file_spec.GetDirectory(); -#elif defined (__linux__) - static ConstString g_lldb_user_plugin_dir; - if (!g_lldb_user_plugin_dir) - { - // XDG Base Directory Specification - // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html - // If XDG_DATA_HOME exists, use that, otherwise use ~/.local/share/lldb. - FileSpec lldb_file_spec; - const char *xdg_data_home = getenv("XDG_DATA_HOME"); - if (xdg_data_home && xdg_data_home[0]) - { - std::string user_plugin_dir (xdg_data_home); - user_plugin_dir += "/lldb"; - lldb_file_spec.SetFile (user_plugin_dir.c_str(), true); - } - else - { - const char *home_dir = getenv("HOME"); - if (home_dir && home_dir[0]) - { - std::string user_plugin_dir (home_dir); - user_plugin_dir += "/.local/share/lldb"; - lldb_file_spec.SetFile (user_plugin_dir.c_str(), true); - } - } - - if (lldb_file_spec.Exists()) - g_lldb_user_plugin_dir.SetCString(lldb_file_spec.GetPath().c_str()); - if (log) - log->Printf("Host::GetLLDBPath(ePathTypeLLDBUserPlugins) => '%s'", g_lldb_user_plugin_dir.GetCString()); - } - file_spec.GetDirectory() = g_lldb_user_plugin_dir; - return (bool)file_spec.GetDirectory(); -#endif - // TODO: where would user LLDB plug-ins be located on other systems? - return false; - } - - case ePathTypeLLDBTempSystemDir: - { - static ConstString g_lldb_tmp_dir; - if (!g_lldb_tmp_dir) - { - const char *tmpdir_cstr = getenv("TMPDIR"); - if (tmpdir_cstr == NULL) - { - tmpdir_cstr = getenv("TMP"); - if (tmpdir_cstr == NULL) - tmpdir_cstr = getenv("TEMP"); - } - if (tmpdir_cstr) - { - StreamString pid_tmpdir; - pid_tmpdir.Printf("%s/lldb", tmpdir_cstr); - if (FileSystem::MakeDirectory(pid_tmpdir.GetString().c_str(), eFilePermissionsDirectoryDefault) - .Success()) - { - pid_tmpdir.Printf("/%" PRIu64, Host::GetCurrentProcessID()); - if (FileSystem::MakeDirectory(pid_tmpdir.GetString().c_str(), eFilePermissionsDirectoryDefault) - .Success()) - { - // Make an atexit handler to clean up the process specify LLDB temp dir - // and all of its contents. - ::atexit (CleanupProcessSpecificLLDBTempDir); - g_lldb_tmp_dir.SetCString(pid_tmpdir.GetString().c_str()); - if (log) - log->Printf("Host::GetLLDBPath(ePathTypeLLDBTempSystemDir) => '%s'", g_lldb_tmp_dir.GetCString()); - - } - } - } - } - file_spec.GetDirectory() = g_lldb_tmp_dir; - return (bool)file_spec.GetDirectory(); - } - } - - return false; -} - #ifndef _WIN32 const char * @@ -1425,7 +1085,7 @@ // output of the command into this file. We will later read this file // if all goes well and fill the data into "command_output_ptr" FileSpec tmpdir_file_spec; - if (Host::GetLLDBPath (ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) + if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) { tmpdir_file_spec.GetFilename().SetCString("lldb-shell-output.XXXXXX"); strncpy(output_file_path_buffer, tmpdir_file_spec.GetPath().c_str(), sizeof(output_file_path_buffer)); Index: source/Host/common/HostInfoBase.cpp =================================================================== --- source/Host/common/HostInfoBase.cpp +++ source/Host/common/HostInfoBase.cpp @@ -10,6 +10,9 @@ #include "lldb/Host/Config.h" #include "lldb/Core/ArchSpec.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/HostInfoBase.h" @@ -22,6 +25,35 @@ using namespace lldb; using namespace lldb_private; +namespace +{ +void +CleanupProcessSpecificLLDBTempDir() +{ + // Get the process specific LLDB temporary directory and delete it. + FileSpec tmpdir_file_spec; + if (!HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) + return; + + // Remove the LLDB temporary directory if we have one. Set "recurse" to + // true to all files that were created for the LLDB process can be cleaned up. + FileSystem::DeleteDirectory(tmpdir_file_spec.GetDirectory().GetCString(), true); +} +} + +#define COMPUTE_LLDB_PATH(compute_function, member_var) \ + { \ + static bool is_initialized = false; \ + static bool success = false; \ + if (!is_initialized) \ + { \ + is_initialized = true; \ + success = HostInfo::compute_function(member_var); \ + } \ + if (success) \ + result = &member_var; \ + } + uint32_t HostInfoBase::m_number_cpus = 0; std::string HostInfoBase::m_vendor_string; std::string HostInfoBase::m_os_string; @@ -29,6 +61,14 @@ ArchSpec HostInfoBase::m_host_arch_32; ArchSpec HostInfoBase::m_host_arch_64; +FileSpec HostInfoBase::m_lldb_so_dir; +FileSpec HostInfoBase::m_lldb_support_exe_dir; +FileSpec HostInfoBase::m_lldb_headers_dir; +FileSpec HostInfoBase::m_lldb_python_dir; +FileSpec HostInfoBase::m_lldb_system_plugin_dir; +FileSpec HostInfoBase::m_lldb_user_plugin_dir; +FileSpec HostInfoBase::m_lldb_tmp_dir; + uint32_t HostInfoBase::GetNumberCPUS() { @@ -103,6 +143,137 @@ return (m_host_arch_64.IsValid()) ? m_host_arch_64 : m_host_arch_32; } +bool +HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec) +{ + file_spec.Clear(); + +#if defined(LLDB_DISABLE_PYTHON) + if (type == lldb::ePathTypePythonDir) + return false; +#endif + + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + FileSpec *result = nullptr; + switch (type) + { + case lldb::ePathTypeLLDBShlibDir: + COMPUTE_LLDB_PATH(ComputeSharedLibraryDirectory, m_lldb_so_dir) + if (log) + log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBShlibDir) => '%s'", m_lldb_so_dir.GetPath().c_str()); + break; + case lldb::ePathTypeSupportExecutableDir: + COMPUTE_LLDB_PATH(ComputeSupportExeDirectory, m_lldb_support_exe_dir) + if (log) + log->Printf("HostInfoBase::GetLLDBPath(ePathTypeSupportExecutableDir) => '%s'", m_lldb_support_exe_dir.GetPath().c_str()); + break; + case lldb::ePathTypeHeaderDir: + COMPUTE_LLDB_PATH(ComputeHeaderDirectory, m_lldb_headers_dir) + if (log) + log->Printf("HostInfoBase::GetLLDBPath(ePathTypeHeaderDir) => '%s'", m_lldb_headers_dir.GetPath().c_str()); + break; + case lldb::ePathTypePythonDir: + COMPUTE_LLDB_PATH(ComputePythonDirectory, m_lldb_python_dir) + if (log) + log->Printf("HostInfoBase::GetLLDBPath(ePathTypePythonDir) => '%s'", m_lldb_python_dir.GetPath().c_str()); + break; + case lldb::ePathTypeLLDBSystemPlugins: + COMPUTE_LLDB_PATH(ComputeSystemPluginsDirectory, m_lldb_system_plugin_dir) + if (log) + log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBSystemPlugins) => '%s'", m_lldb_system_plugin_dir.GetPath().c_str()); + break; + case lldb::ePathTypeLLDBUserPlugins: + COMPUTE_LLDB_PATH(ComputeUserPluginsDirectory, m_lldb_user_plugin_dir) + if (log) + log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBUserPlugins) => '%s'", m_lldb_user_plugin_dir.GetPath().c_str()); + break; + case lldb::ePathTypeLLDBTempSystemDir: + COMPUTE_LLDB_PATH(ComputeTempFileDirectory, m_lldb_tmp_dir) + if (log) + log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBTempSystemDir) => '%s'", m_lldb_tmp_dir.GetPath().c_str()); + break; + } + + if (!result) + return false; + file_spec = *result; + return true; +} + +bool +HostInfoBase::ComputeSharedLibraryDirectory(FileSpec &file_spec) +{ + // To get paths related to LLDB we get the path to the executable that + // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB", + // on linux this is assumed to be the "lldb" main executable. If LLDB on + // linux is actually in a shared library (liblldb.so) then this function will + // need to be modified to "do the right thing". + + FileSpec lldb_file_spec( + Host::GetModuleFileSpecForHostAddress(reinterpret_cast(reinterpret_cast(HostInfoBase::GetLLDBPath)))); + + // Remove the filename so that this FileSpec only represents the directory. + file_spec.SetFile(lldb_file_spec.GetDirectory().AsCString(), true); + + return (bool)file_spec.GetDirectory(); +} + +bool +HostInfoBase::ComputeSupportExeDirectory(FileSpec &file_spec) +{ + return GetLLDBPath(lldb::ePathTypeLLDBShlibDir, file_spec); +} + +bool +HostInfoBase::ComputeTempFileDirectory(FileSpec &file_spec) +{ + const char *tmpdir_cstr = getenv("TMPDIR"); + if (tmpdir_cstr == NULL) + { + tmpdir_cstr = getenv("TMP"); + if (tmpdir_cstr == NULL) + tmpdir_cstr = getenv("TEMP"); + } + if (!tmpdir_cstr) + return false; + + StreamString pid_tmpdir; + pid_tmpdir.Printf("%s/lldb", tmpdir_cstr); + if (!FileSystem::MakeDirectory(pid_tmpdir.GetString().c_str(), eFilePermissionsDirectoryDefault).Success()) + return false; + + pid_tmpdir.Printf("/%" PRIu64, Host::GetCurrentProcessID()); + if (!FileSystem::MakeDirectory(pid_tmpdir.GetString().c_str(), eFilePermissionsDirectoryDefault).Success()) + return false; + + // Make an atexit handler to clean up the process specify LLDB temp dir + // and all of its contents. + ::atexit(CleanupProcessSpecificLLDBTempDir); + file_spec.SetFile(pid_tmpdir.GetString().c_str(), false); + return true; +} + +bool +HostInfoBase::ComputeHeaderDirectory(FileSpec &file_spec) +{ + // TODO(zturner): Figure out how to compute the header directory for all platforms. + return false; +} + +bool +HostInfoBase::ComputeSystemPluginsDirectory(FileSpec &file_spec) +{ + // TODO(zturner): Figure out how to compute the system plugins directory for all platforms. + return false; +} + +bool +HostInfoBase::ComputeUserPluginsDirectory(FileSpec &file_spec) +{ + // TODO(zturner): Figure out how to compute the user plugins directory for all platforms. + return false; +} + void HostInfoBase::ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64) { Index: source/Host/linux/HostInfoLinux.cpp =================================================================== --- source/Host/linux/HostInfoLinux.cpp +++ source/Host/linux/HostInfoLinux.cpp @@ -148,6 +148,33 @@ return m_distribution_id.c_str(); } +bool +HostInfoLinux::ComputeSystemPluginsDirectory(FileSpec &file_spec) +{ + file_spec.SetFile("/usr/lib/lldb", true); + return true; +} + +bool +HostInfoLinux::ComputeUserPluginsDirectory(FileSpec &file_spec) +{ + // XDG Base Directory Specification + // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html + // If XDG_DATA_HOME exists, use that, otherwise use ~/.local/share/lldb. + FileSpec lldb_file_spec; + const char *xdg_data_home = getenv("XDG_DATA_HOME"); + if (xdg_data_home && xdg_data_home[0]) + { + std::string user_plugin_dir(xdg_data_home); + user_plugin_dir += "/lldb"; + lldb_file_spec.SetFile(user_plugin_dir.c_str(), true); + } + else + lldb_file_spec.SetFile("~/.local/share/lldb", true); + + return true; +} + void HostInfoLinux::ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64) { Index: source/Host/macosx/Host.mm =================================================================== --- source/Host/macosx/Host.mm +++ source/Host/macosx/Host.mm @@ -47,6 +47,7 @@ #include "lldb/Core/StreamString.h" #include "lldb/Host/Endian.h" #include "lldb/Host/FileSpec.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" #include "lldb/Utility/CleanUp.h" @@ -366,19 +367,19 @@ // return LLDB_INVALID_PROCESS_ID; // // FileSpec darwin_debug_file_spec; -// if (!Host::GetLLDBPath (ePathTypeSupportExecutableDir, darwin_debug_file_spec)) +// if (!HostInfo::GetLLDBPath (ePathTypeSupportExecutableDir, darwin_debug_file_spec)) // return LLDB_INVALID_PROCESS_ID; // darwin_debug_file_spec.GetFilename().SetCString("darwin-debug"); -// +// // if (!darwin_debug_file_spec.Exists()) // return LLDB_INVALID_PROCESS_ID; -// +// // char launcher_path[PATH_MAX]; // darwin_debug_file_spec.GetPath(launcher_path, sizeof(launcher_path)); // command_file.Printf("\"%s\" ", launcher_path); -// +// // command_file.Printf("--unix-socket=%s ", unix_socket_name.c_str()); -// +// // if (arch_spec && arch_spec->IsValid()) // { // command_file.Printf("--arch=%s ", arch_spec->GetArchitectureName()); @@ -388,7 +389,7 @@ // { // command_file.PutCString("--disable-aslr "); // } -// +// // command_file.PutCString("-- "); // // if (argv) @@ -402,15 +403,15 @@ // command_file.GetFile().Close(); // if (::chmod (temp_file_path, S_IRWXU | S_IRWXG) != 0) // return LLDB_INVALID_PROCESS_ID; -// +// // CFCMutableDictionary cf_env_dict; -// +// // const bool can_create = true; // if (envp) // { // for (size_t i=0; envp[i] != NULL; ++i) // { -// const char *env_entry = envp[i]; +// const char *env_entry = envp[i]; // const char *equal_pos = strchr(env_entry, '='); // if (equal_pos) // { @@ -422,20 +423,20 @@ // } // } // } -// +// // LSApplicationParameters app_params; // ::memset (&app_params, 0, sizeof (app_params)); // app_params.flags = kLSLaunchDontAddToRecents | kLSLaunchAsync; // app_params.argv = NULL; // app_params.environment = (CFDictionaryRef)cf_env_dict.get(); // -// CFCReleaser command_file_url (::CFURLCreateFromFileSystemRepresentation (NULL, -// (const UInt8 *)temp_file_path, +// CFCReleaser command_file_url (::CFURLCreateFromFileSystemRepresentation (NULL, +// (const UInt8 *)temp_file_path, // strlen(temp_file_path), // false)); -// +// // CFCMutableArray urls; -// +// // // Terminal.app will open the ".command" file we have created // // and run our process inside it which will wait at the entry point // // for us to attach. @@ -455,7 +456,7 @@ // AcceptPIDFromInferior, // connect_url, // &lldb_error); -// +// // ProcessSerialNumber psn; // error = LSOpenURLsWithRole(urls.get(), kLSRolesShell, NULL, &app_params, &psn, 1); // if (error == noErr) @@ -466,7 +467,7 @@ // if (accept_thread_result) // { // pid = (intptr_t)accept_thread_result; -// +// // // Wait for process to be stopped the the entry point by watching // // for the process status to be set to SSTOP which indicates it it // // SIGSTOP'ed at the entry point @@ -521,7 +522,7 @@ StreamString command; FileSpec darwin_debug_file_spec; - if (!Host::GetLLDBPath (ePathTypeSupportExecutableDir, darwin_debug_file_spec)) + if (!HostInfo::GetLLDBPath(ePathTypeSupportExecutableDir, darwin_debug_file_spec)) { error.SetErrorString ("can't locate the 'darwin-debug' executable"); return error; Index: source/Host/macosx/HostInfoMacOSX.mm =================================================================== --- source/Host/macosx/HostInfoMacOSX.mm +++ source/Host/macosx/HostInfoMacOSX.mm @@ -7,11 +7,16 @@ // //===----------------------------------------------------------------------===// +#include "lldb/lldb-python.h" + +#include "lldb/Host/HostInfo.h" #include "lldb/Host/macosx/HostInfoMacOSX.h" #include "lldb/Interpreter/Args.h" - #include "lldb/Utility/SafeMachO.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/raw_ostream.h" + // C++ Includes #include @@ -86,6 +91,107 @@ return false; } +bool +HostInfoMacOSX::ComputeSupportExeDirectory(FileSpec &file_spec) +{ + FileSpec lldb_file_spec; + if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec)) + return false; + char raw_path[PATH_MAX]; + lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); + + char *framework_pos = ::strstr(raw_path, "LLDB.framework"); + if (framework_pos) + { + framework_pos += strlen("LLDB.framework"); +#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) + // Shallow bundle + *framework_pos = '\0'; +#else + // Normal bundle + ::strncpy(framework_pos, "/Resources", PATH_MAX - (framework_pos - raw_path)); +#endif + } + file_spec.SetFile(raw_path, true); + return (bool)file_spec.GetDirectory(); +} + +bool +HostInfoMacOSX::ComputeHeaderDirectory(FileSpec &file_spec) +{ + FileSpec lldb_file_spec; + if (!HostInfo::GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec)) + return false; + + char raw_path[PATH_MAX]; + lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); + + char *framework_pos = ::strstr(raw_path, "LLDB.framework"); + if (framework_pos) + { + framework_pos += strlen("LLDB.framework"); + ::strncpy(framework_pos, "/Headers", PATH_MAX - (framework_pos - raw_path)); + } + file_spec.SetFile(raw_path, true); + return true; +} + +bool +HostInfoMacOSX::ComputePythonDirectory(FileSpec &file_spec) +{ + FileSpec lldb_file_spec; + if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec)) + return false; + + char raw_path[PATH_MAX]; + lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); + + char *framework_pos = ::strstr(raw_path, "LLDB.framework"); + if (framework_pos) + { + framework_pos += strlen("LLDB.framework"); + ::strncpy(framework_pos, "/Resources/Python", PATH_MAX - (framework_pos - raw_path)); + } + else + { + llvm::SmallString<256> python_version_dir; + llvm::raw_svector_ostream os(python_version_dir); + os << "/python" << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION << "/site-packages"; + os.flush(); + + // We may get our string truncated. Should we protect this with an assert? + ::strncat(raw_path, python_version_dir.c_str(), sizeof(raw_path) - strlen(raw_path) - 1); + } + file_spec.SetFile(raw_path, true); + return true; +} + +bool +HostInfoMacOSX::ComputeSystemPluginsDirectory(FileSpec &file_spec) +{ + FileSpec lldb_file_spec; + if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec)) + return false; + char raw_path[PATH_MAX]; + lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); + + char *framework_pos = ::strstr(raw_path, "LLDB.framework"); + if (!framework_pos) + return false; + + framework_pos += strlen("LLDB.framework"); + ::strncpy(framework_pos, "/Resources/PlugIns", PATH_MAX - (framework_pos - raw_path)); + file_spec.SetFile(raw_path, true); + return true; +} + +bool +HostInfoMacOSX::ComputeUserPluginsDirectory(FileSpec &file_spec) +{ + file_spec.SetFile("~/Library/Application Support/LLDB/PlugIns", true); + return true; +} + void HostInfoMacOSX::ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64) { Index: source/Host/posix/HostInfoPosix.cpp =================================================================== --- source/Host/posix/HostInfoPosix.cpp +++ source/Host/posix/HostInfoPosix.cpp @@ -7,8 +7,14 @@ // //===----------------------------------------------------------------------===// +#include "lldb/lldb-python.h" + +#include "lldb/Core/Log.h" #include "lldb/Host/posix/HostInfoPosix.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/raw_ostream.h" + #include #include #include @@ -37,3 +43,73 @@ } return false; } + +bool +HostInfoPosix::ComputeSupportExeDirectory(FileSpec &file_spec) +{ + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + + FileSpec lldb_file_spec; + if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec)) + return false; + + char raw_path[PATH_MAX]; + lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); + + // Most Posix systems (e.g. Linux/*BSD) will attempt to replace a */lib with */bin as the base + // directory for helper exe programs. This will fail if the /lib and /bin directories are + // rooted in entirely different trees. + if (log) + log->Printf("HostInfoPosix::ComputeSupportExeDirectory() attempting to derive the bin path (ePathTypeSupportExecutableDir) from " + "this path: %s", + raw_path); + char *lib_pos = ::strstr(raw_path, "/lib"); + if (lib_pos != nullptr) + { + // First terminate the raw path at the start of lib. + *lib_pos = '\0'; + + // Now write in bin in place of lib. + ::strncpy(lib_pos, "/bin", PATH_MAX - (lib_pos - raw_path)); + + if (log) + log->Printf("Host::%s() derived the bin path as: %s", __FUNCTION__, raw_path); + } + else + { + if (log) + log->Printf("Host::%s() failed to find /lib/liblldb within the shared lib path, bailing on bin path construction", + __FUNCTION__); + } + file_spec.SetFile(raw_path, true); + return (bool)file_spec.GetDirectory(); +} + +bool +HostInfoPosix::ComputeHeaderDirectory(FileSpec &file_spec) +{ + file_spec.SetFile("/opt/local/include/lldb", false); + return true; +} + +bool +HostInfoPosix::ComputePythonDirectory(FileSpec &file_spec) +{ + FileSpec lldb_file_spec; + if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec)) + return false; + + char raw_path[PATH_MAX]; + lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); + + llvm::SmallString<256> python_version_dir; + llvm::raw_svector_ostream os(python_version_dir); + os << "/python" << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION << "/site-packages"; + os.flush(); + + // We may get our string truncated. Should we protect this with an assert? + ::strncat(raw_path, python_version_dir.c_str(), sizeof(raw_path) - strlen(raw_path) - 1); + + file_spec.SetFile(raw_path, true); + return true; +} Index: source/Host/windows/HostInfoWindows.cpp =================================================================== --- source/Host/windows/HostInfoWindows.cpp +++ source/Host/windows/HostInfoWindows.cpp @@ -78,3 +78,18 @@ s.assign(buffer, buffer + dwSize); return true; } + +bool +HostInfoWindows::ComputePythonDirectory(FileSpec &file_spec) +{ + FileSpec lldb_file_spec; + if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec)) + return false; + + char raw_path[PATH_MAX]; + lldb_file_spec.AppendPathComponent("../lib/site-packages"); + lldb_file_spec.GetPath(raw_path, sizeof(raw_path)); + + file_spec.SetFile(raw_path, true); + return true; +} Index: source/Interpreter/ScriptInterpreterPython.cpp =================================================================== --- source/Interpreter/ScriptInterpreterPython.cpp +++ source/Interpreter/ScriptInterpreterPython.cpp @@ -31,7 +31,7 @@ #include "lldb/Core/ConnectionFileDescriptor.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Timer.h" -#include "lldb/Host/Host.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Host/Pipe.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" @@ -2601,7 +2601,7 @@ FileSpec file_spec; char python_dir_path[PATH_MAX]; - if (Host::GetLLDBPath (ePathTypePythonDir, file_spec)) + if (HostInfo::GetLLDBPath(ePathTypePythonDir, file_spec)) { std::string python_path("sys.path.insert(0,\""); size_t orig_len = python_path.length(); @@ -2612,8 +2612,8 @@ PyRun_SimpleString (python_path.c_str()); python_path.resize (orig_len); } - - if (Host::GetLLDBPath (ePathTypeLLDBShlibDir, file_spec)) + + if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, file_spec)) { if (file_spec.GetPath(python_dir_path, sizeof (python_dir_path))) { Index: source/Plugins/Platform/MacOSX/PlatformDarwin.cpp =================================================================== --- source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -1069,7 +1069,7 @@ bool developer_dir_path_valid = false; char developer_dir_path[PATH_MAX]; FileSpec temp_file_spec; - if (Host::GetLLDBPath (ePathTypeLLDBShlibDir, temp_file_spec)) + if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, temp_file_spec)) { if (temp_file_spec.GetPath (developer_dir_path, sizeof(developer_dir_path))) { Index: source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp =================================================================== --- source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp +++ source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp @@ -178,7 +178,7 @@ uint32_t versions[2]; if (objfile->GetSDKVersion(versions, sizeof(versions))) { - if (Host::GetLLDBPath (ePathTypeLLDBShlibDir, fspec)) + if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, fspec)) { std::string path; xcode_contents_path = fspec.GetPath(); Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -24,6 +24,7 @@ #include "lldb/Host/FileSpec.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Host/Socket.h" #include "lldb/Host/TimeValue.h" #include "lldb/Target/Process.h" @@ -683,8 +684,8 @@ if (!debugserver_exists) { // The debugserver binary is in the LLDB.framework/Resources - // directory. - if (Host::GetLLDBPath (ePathTypeSupportExecutableDir, debugserver_file_spec)) + // directory. + if (HostInfo::GetLLDBPath(ePathTypeSupportExecutableDir, debugserver_file_spec)) { debugserver_file_spec.GetFilename().SetCString(DEBUGSERVER_BASENAME); debugserver_exists = debugserver_file_spec.Exists(); @@ -750,7 +751,7 @@ // Binding to port zero, we need to figure out what port it ends up // using using a named pipe... FileSpec tmpdir_file_spec; - if (Host::GetLLDBPath (ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) + if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) { tmpdir_file_spec.GetFilename().SetCString("debugserver-named-pipe.XXXXXX"); strncpy(named_pipe_path, tmpdir_file_spec.GetPath().c_str(), sizeof(named_pipe_path));