diff options
11 files changed, 420 insertions, 312 deletions
diff --git a/lldb/source/Host/common/Host.cpp b/lldb/source/Host/common/Host.cpp index 4aa362ecee5..275b4467447 100644 --- a/lldb/source/Host/common/Host.cpp +++ b/lldb/source/Host/common/Host.cpp @@ -1093,6 +1093,29 @@ Host::GetLLDBPath (PathType path_type, FileSpec &file_spec) ::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__) FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path)); g_lldb_support_exe_dir.SetCString(resolved_path); diff --git a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp index 847f8a05f3d..62f95e14767 100644 --- a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp +++ b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp @@ -23,6 +23,7 @@ // Project includes #include "lldb/Core/Error.h" #include "lldb/Core/Debugger.h" +#include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/ModuleSpec.h" @@ -45,6 +46,20 @@ static uint32_t g_initialize_count = 0; Platform * PlatformLinux::CreateInstance (bool force, const ArchSpec *arch) { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM)); + if (log) + { + const char *arch_name; + if (arch && arch->GetArchitectureName ()) + arch_name = arch->GetArchitectureName (); + else + arch_name = "<null>"; + + const char *triple_cstr = arch ? arch->GetTriple ().getTriple ().c_str() : "<null>"; + + log->Printf ("PlatformLinux::%s(force=%s, arch={%s,%s})", __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr); + } + bool create = force; if (create == false && arch && arch->IsValid()) { @@ -59,7 +74,7 @@ PlatformLinux::CreateInstance (bool force, const ArchSpec *arch) // Only accept "unknown" for the vendor if the host is linux and // it "unknown" wasn't specified (it was just returned because it // was NOT specified_ - case llvm::Triple::UnknownArch: + case llvm::Triple::VendorType::UnknownVendor: create = !arch->TripleVendorWasSpecified(); break; #endif @@ -78,7 +93,7 @@ PlatformLinux::CreateInstance (bool force, const ArchSpec *arch) // Only accept "unknown" for the OS if the host is linux and // it "unknown" wasn't specified (it was just returned because it // was NOT specified) - case llvm::Triple::UnknownOS: + case llvm::Triple::OSType::UnknownOS: create = !arch->TripleOSWasSpecified(); break; #endif @@ -88,8 +103,17 @@ PlatformLinux::CreateInstance (bool force, const ArchSpec *arch) } } } + if (create) + { + if (log) + log->Printf ("PlatformLinux::%s() creating remote-linux platform", __FUNCTION__); return new PlatformLinux(false); + } + + if (log) + log->Printf ("PlatformLinux::%s() aborting creation of remote-linux platform", __FUNCTION__); + return NULL; } @@ -308,8 +332,7 @@ PlatformLinux::GetFileWithUUID (const FileSpec &platform_file, /// Default Constructor //------------------------------------------------------------------ PlatformLinux::PlatformLinux (bool is_host) : - Platform(is_host), // This is the local host platform - m_remote_platform_sp () + PlatformPOSIX(is_host) // This is the local host platform { } @@ -417,10 +440,14 @@ PlatformLinux::GetSoftwareBreakpointTrapOpcode (Target &target, Error PlatformLinux::LaunchProcess (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__); + if (launch_info.GetFlags().Test (eLaunchFlagLaunchInShell)) { const bool is_localhost = true; @@ -438,11 +465,34 @@ PlatformLinux::LaunchProcess (ProcessLaunchInfo &launch_info) } else { - error.SetErrorString ("the platform is not currently connected"); + 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"); + } } return error; } +// 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 (); +} + lldb::ProcessSP PlatformLinux::Attach(ProcessAttachInfo &attach_info, Debugger &debugger, @@ -550,4 +600,3 @@ PlatformLinux::AttachNativeProcess (lldb::pid_t pid, return NativeProcessLinux::AttachToProcess (pid, native_delegate, process_sp); #endif } - diff --git a/lldb/source/Plugins/Platform/Linux/PlatformLinux.h b/lldb/source/Plugins/Platform/Linux/PlatformLinux.h index 39b2c6bfb75..891620d7459 100644 --- a/lldb/source/Plugins/Platform/Linux/PlatformLinux.h +++ b/lldb/source/Plugins/Platform/Linux/PlatformLinux.h @@ -14,11 +14,11 @@ // C++ Includes // Other libraries and framework includes // Project includes -#include "lldb/Target/Platform.h" +#include "Plugins/Platform/POSIX/PlatformPOSIX.h" namespace lldb_private { - class PlatformLinux : public Platform + class PlatformLinux : public PlatformPOSIX { public: @@ -45,11 +45,11 @@ namespace lldb_private { static const char * GetPluginDescriptionStatic (bool is_host); - virtual lldb_private::ConstString - GetPluginName(); + lldb_private::ConstString + GetPluginName() override; - virtual uint32_t - GetPluginVersion() + uint32_t + GetPluginVersion() override { return 1; } @@ -57,51 +57,47 @@ namespace lldb_private { //------------------------------------------------------------ // lldb_private::Platform functions //------------------------------------------------------------ - virtual Error + Error ResolveExecutable (const FileSpec &exe_file, const ArchSpec &arch, lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr); + const FileSpecList *module_search_paths_ptr) override; - virtual const char * - GetDescription () + const char * + GetDescription () override { return GetPluginDescriptionStatic(IsHost()); } - virtual void - GetStatus (Stream &strm); + void + GetStatus (Stream &strm) override; - virtual Error + Error GetFileWithUUID (const FileSpec &platform_file, - const UUID* uuid, FileSpec &local_file); + const UUID* uuid, FileSpec &local_file) override; - virtual bool - GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &proc_info); + bool + GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &proc_info) override; - virtual bool - GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch); + bool + GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) override; - virtual size_t + size_t GetSoftwareBreakpointTrapOpcode (Target &target, - BreakpointSite *bp_site); + BreakpointSite *bp_site) override; - virtual lldb_private::Error - LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info); + lldb_private::Error + LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info) override; - virtual lldb::ProcessSP + lldb::ProcessSP Attach(ProcessAttachInfo &attach_info, Debugger &debugger, - Target *target, Listener &listener, Error &error); + Target *target, Listener &listener, Error &error) override; - // Linux processes can not be launched by spawning and attaching. - virtual bool - CanDebugProcess () - { - return false; - } + bool + CanDebugProcess () override; - virtual void - CalculateTrapHandlerSymbolNames (); + void + CalculateTrapHandlerSymbolNames () override; Error LaunchNativeProcess ( @@ -114,9 +110,6 @@ namespace lldb_private { lldb_private::NativeProcessProtocol::NativeDelegate &native_delegate, NativeProcessProtocolSP &process_sp) override; - protected: - lldb::PlatformSP m_remote_platform_sp; // Allow multiple ways to connect to a remote darwin OS - private: DISALLOW_COPY_AND_ASSIGN (PlatformLinux); }; diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp index 64bc2aefa04..9012ffa5a2c 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -591,135 +591,6 @@ PlatformDarwin::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite } bool -PlatformDarwin::GetRemoteOSVersion () -{ - if (m_remote_platform_sp) - return m_remote_platform_sp->GetOSVersion (m_major_os_version, - m_minor_os_version, - m_update_os_version); - return false; -} - -bool -PlatformDarwin::GetRemoteOSBuildString (std::string &s) -{ - if (m_remote_platform_sp) - return m_remote_platform_sp->GetRemoteOSBuildString (s); - s.clear(); - return false; -} - -bool -PlatformDarwin::GetRemoteOSKernelDescription (std::string &s) -{ - if (m_remote_platform_sp) - return m_remote_platform_sp->GetRemoteOSKernelDescription (s); - s.clear(); - return false; -} - -// Remote Platform subclasses need to override this function -ArchSpec -PlatformDarwin::GetRemoteSystemArchitecture () -{ - if (m_remote_platform_sp) - return m_remote_platform_sp->GetRemoteSystemArchitecture (); - return ArchSpec(); -} - - -const char * -PlatformDarwin::GetHostname () -{ - if (IsHost()) - return Platform::GetHostname(); - - if (m_remote_platform_sp) - return m_remote_platform_sp->GetHostname (); - return NULL; -} - -bool -PlatformDarwin::IsConnected () const -{ - if (IsHost()) - return true; - else if (m_remote_platform_sp) - return m_remote_platform_sp->IsConnected(); - return false; -} - -Error -PlatformDarwin::ConnectRemote (Args& args) -{ - Error error; - if (IsHost()) - { - error.SetErrorStringWithFormat ("can't connect to the host platform '%s', always connected", GetPluginName().GetCString()); - } - else - { - if (!m_remote_platform_sp) - m_remote_platform_sp = Platform::Create ("remote-gdb-server", error); - - if (m_remote_platform_sp && error.Success()) - error = m_remote_platform_sp->ConnectRemote (args); - else - error.SetErrorString ("failed to create a 'remote-gdb-server' platform"); - - if (error.Fail()) - m_remote_platform_sp.reset(); - } - - if (error.Success() && m_remote_platform_sp) - { - if (m_options.get()) - { - OptionGroupOptions* options = m_options.get(); - OptionGroupPlatformRSync* m_rsync_options = (OptionGroupPlatformRSync*)options->GetGroupWithOption('r'); - OptionGroupPlatformSSH* m_ssh_options = (OptionGroupPlatformSSH*)options->GetGroupWithOption('s'); - OptionGroupPlatformCaching* m_cache_options = (OptionGroupPlatformCaching*)options->GetGroupWithOption('c'); - - if (m_rsync_options->m_rsync) - { - SetSupportsRSync(true); - SetRSyncOpts(m_rsync_options->m_rsync_opts.c_str()); - SetRSyncPrefix(m_rsync_options->m_rsync_prefix.c_str()); - SetIgnoresRemoteHostname(m_rsync_options->m_ignores_remote_hostname); - } - if (m_ssh_options->m_ssh) - { - SetSupportsSSH(true); - SetSSHOpts(m_ssh_options->m_ssh_opts.c_str()); - } - SetLocalCacheDirectory(m_cache_options->m_cache_dir.c_str()); - } - } - - return error; -} - -Error -PlatformDarwin::DisconnectRemote () -{ - Error error; - - if (IsHost()) - { - error.SetErrorStringWithFormat ("can't disconnect from the host platform '%s', always connected", GetPluginName().GetCString()); - } - else - { - if (m_remote_platform_sp) - error = m_remote_platform_sp->DisconnectRemote (); - else - error.SetErrorString ("the platform is not currently connected"); - } - return error; -} - - -bool PlatformDarwin::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) { bool sucess = false; @@ -735,8 +606,6 @@ PlatformDarwin::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_in return sucess; } - - uint32_t PlatformDarwin::FindProcesses (const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) @@ -776,35 +645,6 @@ PlatformDarwin::LaunchProcess (ProcessLaunchInfo &launch_info) } lldb::ProcessSP -PlatformDarwin::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) -{ - ProcessSP process_sp; - - if (IsHost()) - { - // We are going to hand this process off to debugserver which will be in charge of setting the exit status. - // We still need to reap it from lldb but if we let the monitor thread also set the exit status, we set up a - // race between debugserver & us for who will find out about the debugged process's death. - launch_info.GetFlags().Set(eLaunchFlagDontSetExitStatus); - process_sp = Platform::DebugProcess (launch_info, debugger, target, listener, error); - } - else - { - if (m_remote_platform_sp) - process_sp = m_remote_platform_sp->DebugProcess (launch_info, debugger, target, listener, error); - else - error.SetErrorString ("the platform is not currently connected"); - } - return process_sp; - -} - - -lldb::ProcessSP PlatformDarwin::Attach (ProcessAttachInfo &attach_info, Debugger &debugger, Target *target, @@ -855,31 +695,6 @@ PlatformDarwin::Attach (ProcessAttachInfo &attach_info, return process_sp; } -const char * -PlatformDarwin::GetUserName (uint32_t uid) -{ - // Check the cache in Platform in case we have already looked this uid up - const char *user_name = Platform::GetUserName(uid); - if (user_name) - return user_name; - - if (IsRemote() && m_remote_platform_sp) - return m_remote_platform_sp->GetUserName(uid); - return NULL; -} - -const char * -PlatformDarwin::GetGroupName (uint32_t gid) -{ - const char *group_name = Platform::GetGroupName(gid); - if (group_name) - return group_name; - - if (IsRemote() && m_remote_platform_sp) - return m_remote_platform_sp->GetGroupName(gid); - return NULL; -} - bool PlatformDarwin::ModuleIsExcludedForNonModuleSpecificSearches (lldb_private::Target &target, const lldb::ModuleSP &module_sp) { diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h index d96f11bbfae..21529a8e961 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h @@ -54,37 +54,6 @@ public: lldb_private::BreakpointSite *bp_site); virtual bool - GetRemoteOSVersion (); - - virtual bool - GetRemoteOSBuildString (std::string &s); - - virtual bool - GetRemoteOSKernelDescription (std::string &s); - - // Remote Platform subclasses need to override this function - virtual lldb_private::ArchSpec - GetRemoteSystemArchitecture (); - - virtual bool - IsConnected () const; - - virtual lldb_private::Error - ConnectRemote (lldb_private::Args& args); - - virtual lldb_private::Error - DisconnectRemote (); - - virtual const char * - GetHostname (); - - virtual const char * - GetUserName (uint32_t uid); - - virtual const char * - GetGroupName (uint32_t gid); - - virtual bool GetProcessInfo (lldb::pid_t pid, lldb_private::ProcessInstanceInfo &proc_info); @@ -99,13 +68,6 @@ public: LaunchProcess (lldb_private::ProcessLaunchInfo &launch_info); virtual lldb::ProcessSP - DebugProcess (lldb_private::ProcessLaunchInfo &launch_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 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 diff --git a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp index bb07d999c4c..f0dab8d7234 100644 --- a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp +++ b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp @@ -20,6 +20,7 @@ #include "lldb/Host/File.h" #include "lldb/Host/FileSpec.h" #include "lldb/Host/Host.h" +#include "lldb/Target/ProcessLaunchInfo.h" using namespace lldb; using namespace lldb_private; @@ -57,6 +58,16 @@ PlatformPOSIX::GetConnectionOptions (lldb_private::CommandInterpreter& interpret return m_options.get(); } +bool +PlatformPOSIX::IsConnected () const +{ + if (IsHost()) + return true; + else if (m_remote_platform_sp) + return m_remote_platform_sp->IsConnected(); + return false; +} + lldb_private::Error PlatformPOSIX::RunShellCommand (const char *command, // Shouldn't be NULL const char *working_dir, // Pass NULL to use the current working directory @@ -589,6 +600,176 @@ PlatformPOSIX::SetRemoteWorkingDirectory(const lldb_private::ConstString &path) return Platform::SetRemoteWorkingDirectory(path); } +bool +PlatformPOSIX::GetRemoteOSVersion () +{ + if (m_remote_platform_sp) + return m_remote_platform_sp->GetOSVersion (m_major_os_version, + m_minor_os_version, + m_update_os_version); + return false; +} + +bool +PlatformPOSIX::GetRemoteOSBuildString (std::string &s) +{ + if (m_remote_platform_sp) + return m_remote_platform_sp->GetRemoteOSBuildString (s); + s.clear(); + return false; +} + +bool +PlatformPOSIX::GetRemoteOSKernelDescription (std::string &s) +{ + if (m_remote_platform_sp) + return m_remote_platform_sp->GetRemoteOSKernelDescription (s); + s.clear(); + return false; +} + +// Remote Platform subclasses need to override this function +ArchSpec +PlatformPOSIX::GetRemoteSystemArchitecture () +{ + if (m_remote_platform_sp) + return m_remote_platform_sp->GetRemoteSystemArchitecture (); + return ArchSpec(); +} + +const char * +PlatformPOSIX::GetHostname () +{ + if (IsHost()) + return Platform::GetHostname(); + + if (m_remote_platform_sp) + return m_remote_platform_sp->GetHostname (); + return NULL; +} + +const char * +PlatformPOSIX::GetUserName (uint32_t uid) +{ + // Check the cache in Platform in case we have already looked this uid up + const char *user_name = Platform::GetUserName(uid); + if (user_name) + return user_name; + + if (IsRemote() && m_remote_platform_sp) + return m_remote_platform_sp->GetUserName(uid); + return NULL; +} + +const char * +PlatformPOSIX::GetGroupName (uint32_t gid) +{ + const char *group_name = Platform::GetGroupName(gid); + if (group_name) + return group_name; + + if (IsRemote() && m_remote_platform_sp) + return m_remote_platform_sp->GetGroupName(gid); + return NULL; +} + +Error +PlatformPOSIX::ConnectRemote (Args& args) +{ + Error error; + if (IsHost()) + { + error.SetErrorStringWithFormat ("can't connect to the host platform '%s', always connected", GetPluginName().GetCString()); + } + else + { + if (!m_remote_platform_sp) + m_remote_platform_sp = Platform::Create ("remote-gdb-server", error); + + if (m_remote_platform_sp && error.Success()) + error = m_remote_platform_sp->ConnectRemote (args); + else + error.SetErrorString ("failed to create a 'remote-gdb-server' platform"); + + if (error.Fail()) + m_remote_platform_sp.reset(); + } + + if (error.Success() && m_remote_platform_sp) + { + if (m_options.get()) + { + OptionGroupOptions* options = m_options.get(); + OptionGroupPlatformRSync* m_rsync_options = (OptionGroupPlatformRSync*)options->GetGroupWithOption('r'); + OptionGroupPlatformSSH* m_ssh_options = (OptionGroupPlatformSSH*)options->GetGroupWithOption('s'); + OptionGroupPlatformCaching* m_cache_options = (OptionGroupPlatformCaching*)options->GetGroupWithOption('c'); + + if (m_rsync_options->m_rsync) + { + SetSupportsRSync(true); + SetRSyncOpts(m_rsync_options->m_rsync_opts.c_str()); + SetRSyncPrefix(m_rsync_options->m_rsync_prefix.c_str()); + SetIgnoresRemoteHostname(m_rsync_options->m_ignores_remote_hostname); + } + if (m_ssh_options->m_ssh) + { + SetSupportsSSH(true); + SetSSHOpts(m_ssh_options->m_ssh_opts.c_str()); + } + SetLocalCacheDirectory(m_cache_options->m_cache_dir.c_str()); + } + } + + return error; +} + +Error +PlatformPOSIX::DisconnectRemote () +{ + Error error; + + if (IsHost()) + { + error.SetErrorStringWithFormat ("can't disconnect from the host platform '%s', always connected", GetPluginName().GetCString()); + } + else + { + if (m_remote_platform_sp) + error = m_remote_platform_sp->DisconnectRemote (); + else + error.SetErrorString ("the platform is not currently connected"); + } + return error; +} + +lldb::ProcessSP +PlatformPOSIX::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) +{ + ProcessSP process_sp; + + if (IsHost()) + { + // We are going to hand this process off to debugserver which will be in charge of setting the exit status. + // We still need to reap it from lldb but if we let the monitor thread also set the exit status, we set up a + // race between debugserver & us for who will find out about the debugged process's death. + launch_info.GetFlags().Set(eLaunchFlagDontSetExitStatus); + process_sp = Platform::DebugProcess (launch_info, debugger, target, listener, error); + } + else + { + if (m_remote_platform_sp) + process_sp = m_remote_platform_sp->DebugProcess (launch_info, debugger, target, listener, error); + else + error.SetErrorString ("the platform is not currently connected"); + } + return process_sp; + +} + void PlatformPOSIX::CalculateTrapHandlerSymbolNames () { diff --git a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h index 130c84bdfac..374e36495d8 100644 --- a/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h +++ b/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h @@ -33,7 +33,16 @@ public: //------------------------------------------------------------ virtual lldb_private::OptionGroupOptions* GetConnectionOptions (lldb_private::CommandInterpreter& interpreter); - + + const char * + GetHostname () override; + + const char * + GetUserName (uint32_t uid) override; + + const char * + GetGroupName (uint32_t gid) override; + virtual lldb_private::Error PutFile (const lldb_private::FileSpec& source, const lldb_private::FileSpec& destination, @@ -79,7 +88,22 @@ public: virtual bool SetRemoteWorkingDirectory(const lldb_private::ConstString &path); - + + bool + GetRemoteOSVersion () override; + + bool + GetRemoteOSBuildString (std::string &s) override; + + bool + GetRemoteOSKernelDescription (std::string &s) override; + + lldb_private::ArchSpec + GetRemoteSystemArchitecture () override; + + bool + IsConnected () const override; + virtual lldb_private::Error RunShellCommand (const char *command, // Shouldn't be NULL const char *working_dir, // Pass NULL to use the current working directory @@ -103,6 +127,13 @@ public: virtual lldb_private::Error Unlink (const char *path); + lldb::ProcessSP + DebugProcess (lldb_private::ProcessLaunchInfo &launch_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; + virtual std::string GetPlatformSpecificConnectionInformation(); @@ -114,6 +145,12 @@ public: virtual void CalculateTrapHandlerSymbolNames (); + lldb_private::Error + ConnectRemote (lldb_private::Args& args) override; + + lldb_private::Error + DisconnectRemote () override; + protected: std::unique_ptr<lldb_private::OptionGroupOptions> m_options; diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp index 6641998c0ba..4e9ec8b3b23 100644 --- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp +++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp @@ -24,6 +24,7 @@ #include "lldb/Core/ConnectionFileDescriptor.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/PluginManager.h" @@ -346,9 +347,13 @@ PlatformRemoteGDBServer::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &p Error PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info) { + 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"); @@ -378,7 +383,9 @@ PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info) const char *arch_triple = arch_spec.GetTriple().str().c_str(); m_gdb_client.SendLaunchArchPacket(arch_triple); - + if (log) + log->Printf ("PlatformRemoteGDBServer::%s() set launch architecture triple to '%s'", __FUNCTION__, arch_triple ? arch_triple : "<NULL>"); + const uint32_t old_packet_timeout = m_gdb_client.SetPacketTimeout (5); int arg_packet_err = m_gdb_client.SendArgumentsPacket (launch_info); m_gdb_client.SetPacketTimeout (old_packet_timeout); @@ -389,11 +396,23 @@ PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info) { pid = m_gdb_client.GetCurrentProcessID (); if (pid != LLDB_INVALID_PROCESS_ID) + { launch_info.SetProcessID (pid); + if (log) + log->Printf ("PlatformRemoteGDBServer::%s() pid %" PRIu64 " launched successfully", __FUNCTION__, pid); + } + else + { + 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. + } } else { error.SetErrorString (error_str.c_str()); + if (log) + log->Printf ("PlatformRemoteGDBServer::%s() launch failed: %s", __FUNCTION__, error.AsCString ()); } } else diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index d3ab3b8ec5f..be90eb2b2c9 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -29,7 +29,11 @@ // Project includes #include "ProcessGDBRemoteLog.h" -#define DEBUGSERVER_BASENAME "debugserver" +#if defined(__APPLE__) +# define DEBUGSERVER_BASENAME "debugserver" +#else +# define DEBUGSERVER_BASENAME "lldb-gdbserver" +#endif using namespace lldb; using namespace lldb_private; @@ -650,6 +654,10 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname, lldb_private::ProcessLaunchInfo &launch_info, uint16_t &out_port) { + Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); + if (log) + log->Printf ("GDBRemoteCommunication::%s(hostname=%s, in_port=%" PRIu16 ", out_port=%" PRIu16, __FUNCTION__, hostname ? hostname : "<empty>", in_port, out_port); + out_port = in_port; Error error; // If we locate debugserver, keep that located version around @@ -662,7 +670,11 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname, // to the debugserver to use and use it if we do. const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH"); if (env_debugserver_path) + { debugserver_file_spec.SetFile (env_debugserver_path, false); + if (log) + log->Printf ("GDBRemoteCommunication::%s() gdb-remote stub exe path set from environment variable: %s", __FUNCTION__, env_debugserver_path); + } else debugserver_file_spec = g_debugserver_file_spec; bool debugserver_exists = debugserver_file_spec.Exists(); @@ -676,10 +688,16 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname, debugserver_exists = debugserver_file_spec.Exists(); if (debugserver_exists) { + if (log) + log->Printf ("GDBRemoteCommunication::%s() found gdb-remote stub exe '%s'", __FUNCTION__, debugserver_file_spec.GetPath ().c_str ()); + g_debugserver_file_spec = debugserver_file_spec; } else { + if (log) + log->Printf ("GDBRemoteCommunication::%s() could not find gdb-remote stub exe '%s'", __FUNCTION__, debugserver_file_spec.GetPath ().c_str ()); + g_debugserver_file_spec.Clear(); debugserver_file_spec.Clear(); } diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp index 8cda558fa5a..b9d59e72ed9 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp @@ -1824,14 +1824,18 @@ GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote #ifdef _WIN32 return SendErrorResponse(9); #else + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); + // Spawn a local debugserver as a platform so we can then attach or launch // a process... if (m_is_platform) { + if (log) + log->Printf ("GDBRemoteCommunicationServer::%s() called", __FUNCTION__); + // Sleep and wait a bit for debugserver to start to listen... ConnectionFileDescriptor file_conn; - Error error; std::string hostname; // TODO: /tmp/ should not be hardcoded. User might want to override /tmp // with the TMPDIR environment variable @@ -1852,53 +1856,57 @@ GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote // Spawn a new thread to accept the port that gets bound after // binding to port 0 (zero). - if (error.Success()) - { - // Spawn a debugserver and try to get the port it listens to. - ProcessLaunchInfo debugserver_launch_info; - if (hostname.empty()) - hostname = "127.0.0.1"; - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); - if (log) - log->Printf("Launching debugserver with: %s:%u...\n", hostname.c_str(), port); + // Spawn a debugserver and try to get the port it listens to. + ProcessLaunchInfo debugserver_launch_info; + if (hostname.empty()) + hostname = "127.0.0.1"; + if (log) + log->Printf("Launching debugserver with: %s:%u...\n", hostname.c_str(), port); - debugserver_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false); - - error = StartDebugserverProcess (hostname.empty() ? NULL : hostname.c_str(), - port, - debugserver_launch_info, - port); + debugserver_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false); - lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID(); + Error error = StartDebugserverProcess (hostname.empty() ? NULL : hostname.c_str(), + port, + debugserver_launch_info, + port); + lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID(); - if (debugserver_pid != LLDB_INVALID_PROCESS_ID) - { - Mutex::Locker locker (m_spawned_pids_mutex); - m_spawned_pids.insert(debugserver_pid); - if (port > 0) - AssociatePortWithProcess(port, debugserver_pid); - } - else - { - if (port > 0) - FreePort (port); - } - if (error.Success()) - { - char response[256]; - const int response_len = ::snprintf (response, sizeof(response), "pid:%" PRIu64 ";port:%u;", debugserver_pid, port + m_port_offset); - assert (response_len < (int)sizeof(response)); - PacketResult packet_result = SendPacketNoLock (response, response_len); + if (debugserver_pid != LLDB_INVALID_PROCESS_ID) + { + Mutex::Locker locker (m_spawned_pids_mutex); + m_spawned_pids.insert(debugserver_pid); + if (port > 0) + AssociatePortWithProcess(port, debugserver_pid); + } + else + { + if (port > 0) + FreePort (port); + } - if (packet_result != PacketResult::Success) - { - if (debugserver_pid != LLDB_INVALID_PROCESS_ID) - ::kill (debugserver_pid, SIGINT); - } - return packet_result; + if (error.Success()) + { + if (log) + log->Printf ("GDBRemoteCommunicationServer::%s() debugserver launched successfully as pid %" PRIu64, __FUNCTION__, debugserver_pid); + + char response[256]; + const int response_len = ::snprintf (response, sizeof(response), "pid:%" PRIu64 ";port:%u;", debugserver_pid, port + m_port_offset); + assert (response_len < (int)sizeof(response)); + PacketResult packet_result = SendPacketNoLock (response, response_len); + + if (packet_result != PacketResult::Success) + { + if (debugserver_pid != LLDB_INVALID_PROCESS_ID) + ::kill (debugserver_pid, SIGINT); } + return packet_result; + } + else + { + if (log) + log->Printf ("GDBRemoteCommunicationServer::%s() debugserver launch failed: %s", __FUNCTION__, error.AsCString ()); } } return SendErrorResponse (9); diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index bc46df96788..d48df888381 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -2368,7 +2368,8 @@ Target::Launch (Listener &listener, ProcessLaunchInfo &launch_info) if (!launch_info.GetArchitecture().IsValid()) launch_info.GetArchitecture() = GetArchitecture(); - + + // If we're not already connected to the process, and if we have a platform that can launch a process for debugging, go ahead and do that here. if (state != eStateConnected && platform_sp && platform_sp->CanDebugProcess ()) { m_process_sp = GetPlatform()->DebugProcess (launch_info, @@ -2385,10 +2386,12 @@ Target::Launch (Listener &listener, ProcessLaunchInfo &launch_info) } else { + // Use a Process plugin to construct the process. const char *plugin_name = launch_info.GetProcessPluginName(); CreateProcess (listener, plugin_name, NULL); } - + + // Since we didn't have a platform launch the process, launch it here. if (m_process_sp) error = m_process_sp->Launch (launch_info); } |