[Lldb-commits] [PATCH] enable lldb-platform exe for platform "remote-linux"
Todd Fiala
todd.fiala at gmail.com
Mon Jul 21 18:12:35 PDT 2014
This change enables lldb-platform for Linux. In addition, it does the
following:
* fixes Host::GetLLDBPath() to work on Linux/*BSD for
ePathTypeSupportExecutableDir-relative paths.
* adds more logging and comments around lldb-platform startup and remote
lldb-platform usage.
* refactors lldb-platform remote-* support for Darwin and Linux into
PlatformPOSIX. This, in theory, is the bulk of what is needed for *BSD to
make remote connections to lldb-platform as well (although I haven't tested
that yet).
* teaches GDBRemoteCommunication to use lldb-gdbserver for non-Apple hosts.
See attached patch for details.
Tested:
Linux - Ubuntu 14.04 x86_64, local test suite, clang-3.5-built lldb
MacOSX - OS X 10.9.4 x86_64, local test suite (x86_64 architecture), Xcode
6 Beta 3-built lldb.
--
-Todd
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20140721/77137cfe/attachment.html>
-------------- next part --------------
diff --git a/source/Host/common/Host.cpp b/source/Host/common/Host.cpp
index 0006a61..d5c91cd 100644
--- a/source/Host/common/Host.cpp
+++ b/source/Host/common/Host.cpp
@@ -1092,6 +1092,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/source/Plugins/Platform/Linux/PlatformLinux.cpp b/source/Plugins/Platform/Linux/PlatformLinux.cpp
index 847f8a0..62f95e1 100644
--- a/source/Plugins/Platform/Linux/PlatformLinux.cpp
+++ b/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/source/Plugins/Platform/Linux/PlatformLinux.h b/source/Plugins/Platform/Linux/PlatformLinux.h
index 39b2c6b..891620d 100644
--- a/source/Plugins/Platform/Linux/PlatformLinux.h
+++ b/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/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index 64bc2ae..9012ffa 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/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/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/source/Plugins/Platform/MacOSX/PlatformDarwin.h
index d96f11b..21529a8 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwin.h
+++ b/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/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
index bb07d99..f0dab8d 100644
--- a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ b/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/source/Plugins/Platform/POSIX/PlatformPOSIX.h b/source/Plugins/Platform/POSIX/PlatformPOSIX.h
index 130c84b..374e364 100644
--- a/source/Plugins/Platform/POSIX/PlatformPOSIX.h
+++ b/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/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index 6641998..4e9ec8b 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/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/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index d3ab3b8..be90eb2 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/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/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index 8cda558..b9d59e7 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/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/source/Target/Target.cpp b/source/Target/Target.cpp
index bc46df9..d48df88 100644
--- a/source/Target/Target.cpp
+++ b/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);
}
More information about the lldb-commits
mailing list