summaryrefslogtreecommitdiffstats
path: root/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp')
-rw-r--r--source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp192
1 files changed, 172 insertions, 20 deletions
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index 4aeec03..248abaf 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -194,6 +194,47 @@ PlatformRemoteGDBServer::GetRemoteSystemArchitecture ()
return m_gdb_client.GetSystemArchitecture();
}
+lldb_private::ConstString
+PlatformRemoteGDBServer::GetRemoteWorkingDirectory()
+{
+ if (IsConnected())
+ {
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+ std::string cwd;
+ if (m_gdb_client.GetWorkingDir(cwd))
+ {
+ ConstString working_dir(cwd.c_str());
+ if (log)
+ log->Printf("PlatformRemoteGDBServer::GetRemoteWorkingDirectory() -> '%s'", working_dir.GetCString());
+ return working_dir;
+ }
+ else
+ {
+ return ConstString();
+ }
+ }
+ else
+ {
+ return Platform::GetRemoteWorkingDirectory();
+ }
+}
+
+bool
+PlatformRemoteGDBServer::SetRemoteWorkingDirectory(const lldb_private::ConstString &path)
+{
+ if (IsConnected())
+ {
+ // Clear the working directory it case it doesn't get set correctly. This will
+ // for use to re-read it
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+ if (log)
+ log->Printf("PlatformRemoteGDBServer::SetRemoteWorkingDirectory('%s')", path.GetCString());
+ return m_gdb_client.SetWorkingDir(path.GetCString()) == 0;
+ }
+ else
+ return Platform::SetRemoteWorkingDirectory(path);
+}
+
bool
PlatformRemoteGDBServer::IsConnected () const
{
@@ -220,8 +261,10 @@ PlatformRemoteGDBServer::ConnectRemote (Args& args)
{
if (m_gdb_client.HandshakeWithServer(&error))
{
- m_gdb_client.QueryNoAckModeSupported();
m_gdb_client.GetHostInfo();
+ // If a working directory was set prior to connecting, send it down now
+ if (m_working_dir)
+ m_gdb_client.SetWorkingDir(m_working_dir.GetCString());
#if 0
m_gdb_client.TestPacketSpeed(10000);
#endif
@@ -229,6 +272,8 @@ PlatformRemoteGDBServer::ConnectRemote (Args& args)
else
{
m_gdb_client.Disconnect();
+ if (error.Success())
+ error.SetErrorString("handshake failed");
}
}
}
@@ -237,11 +282,6 @@ PlatformRemoteGDBServer::ConnectRemote (Args& args)
error.SetErrorString ("\"platform connect\" takes a single argument: <connect-url>");
}
}
-
- if (error.Success())
- {
-
- }
return error;
}
@@ -324,7 +364,6 @@ PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info)
}
// Send the environment and the program + arguments after we connect
- const char **argv = launch_info.GetArguments().GetConstArgumentVector();
const char **envp = launch_info.GetEnvironmentEntries().GetConstArgumentVector();
if (envp)
@@ -343,7 +382,7 @@ PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info)
m_gdb_client.SendLaunchArchPacket(arch_triple);
const uint32_t old_packet_timeout = m_gdb_client.SetPacketTimeout (5);
- int arg_packet_err = m_gdb_client.SendArgumentsPacket (argv);
+ int arg_packet_err = m_gdb_client.SendArgumentsPacket (launch_info);
m_gdb_client.SetPacketTimeout (old_packet_timeout);
if (arg_packet_err == 0)
{
@@ -367,6 +406,80 @@ PlatformRemoteGDBServer::LaunchProcess (ProcessLaunchInfo &launch_info)
}
lldb::ProcessSP
+PlatformRemoteGDBServer::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)
+{
+ lldb::ProcessSP process_sp;
+ if (IsRemote())
+ {
+ if (IsConnected())
+ {
+ lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
+ uint16_t port = m_gdb_client.LaunchGDBserverAndGetPort(debugserver_pid);
+
+ if (port == 0)
+ {
+ error.SetErrorStringWithFormat ("unable to launch a GDB server on '%s'", GetHostname ());
+ }
+ else
+ {
+ if (target == NULL)
+ {
+ TargetSP new_target_sp;
+
+ error = debugger.GetTargetList().CreateTarget (debugger,
+ NULL,
+ NULL,
+ false,
+ NULL,
+ new_target_sp);
+ target = new_target_sp.get();
+ }
+ else
+ error.Clear();
+
+ if (target && error.Success())
+ {
+ debugger.GetTargetList().SetSelectedTarget(target);
+
+ // The darwin always currently uses the GDB remote debugger plug-in
+ // so even when debugging locally we are debugging remotely!
+ process_sp = target->CreateProcess (listener, "gdb-remote", NULL);
+
+ if (process_sp)
+ {
+ char connect_url[256];
+ const char *override_hostname = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_HOSTNAME");
+ const char *port_offset_c_str = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_PORT_OFFSET");
+ int port_offset = port_offset_c_str ? ::atoi(port_offset_c_str) : 0;
+ const int connect_url_len = ::snprintf (connect_url,
+ sizeof(connect_url),
+ "connect://%s:%u",
+ override_hostname ? override_hostname : GetHostname (),
+ port + port_offset);
+ assert (connect_url_len < (int)sizeof(connect_url));
+ error = process_sp->ConnectRemote (NULL, connect_url);
+ if (error.Success())
+ error = process_sp->Launch(launch_info);
+ else if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
+ m_gdb_client.KillSpawnedProcess(debugserver_pid);
+ }
+ }
+ }
+ }
+ else
+ {
+ error.SetErrorString("not connected to remote gdb server");
+ }
+ }
+ return process_sp;
+
+}
+
+lldb::ProcessSP
PlatformRemoteGDBServer::Attach (lldb_private::ProcessAttachInfo &attach_info,
Debugger &debugger,
Target *target, // Can be NULL, if NULL create a new target, else use existing one
@@ -441,17 +554,42 @@ PlatformRemoteGDBServer::Attach (lldb_private::ProcessAttachInfo &attach_info,
return process_sp;
}
-uint32_t
-PlatformRemoteGDBServer::MakeDirectory (const std::string &path,
- mode_t mode)
+Error
+PlatformRemoteGDBServer::MakeDirectory (const char *path, uint32_t mode)
{
- return m_gdb_client.MakeDirectory(path,mode);
+ Error error = m_gdb_client.MakeDirectory(path,mode);
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+ if (log)
+ log->Printf ("PlatformRemoteGDBServer::MakeDirectory(path='%s', mode=%o) error = %u (%s)", path, mode, error.GetError(), error.AsCString());
+ return error;
}
+
+Error
+PlatformRemoteGDBServer::GetFilePermissions (const char *path, uint32_t &file_permissions)
+{
+ Error error = m_gdb_client.GetFilePermissions(path, file_permissions);
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+ if (log)
+ log->Printf ("PlatformRemoteGDBServer::GetFilePermissions(path='%s', file_permissions=%o) error = %u (%s)", path, file_permissions, error.GetError(), error.AsCString());
+ return error;
+}
+
+Error
+PlatformRemoteGDBServer::SetFilePermissions (const char *path, uint32_t file_permissions)
+{
+ Error error = m_gdb_client.SetFilePermissions(path, file_permissions);
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+ if (log)
+ log->Printf ("PlatformRemoteGDBServer::SetFilePermissions(path='%s', file_permissions=%o) error = %u (%s)", path, file_permissions, error.GetError(), error.AsCString());
+ return error;
+}
+
+
lldb::user_id_t
PlatformRemoteGDBServer::OpenFile (const lldb_private::FileSpec& file_spec,
uint32_t flags,
- mode_t mode,
+ uint32_t mode,
Error &error)
{
return m_gdb_client.OpenFile (file_spec, flags, mode, error);
@@ -469,13 +607,6 @@ PlatformRemoteGDBServer::GetFileSize (const lldb_private::FileSpec& file_spec)
return m_gdb_client.GetFileSize(file_spec);
}
-uint32_t
-PlatformRemoteGDBServer::GetFilePermissions (const lldb_private::FileSpec &file_spec,
- lldb_private::Error &error)
-{
- return m_gdb_client.GetFilePermissions(file_spec, error);
-}
-
uint64_t
PlatformRemoteGDBServer::ReadFile (lldb::user_id_t fd,
uint64_t offset,
@@ -505,6 +636,27 @@ PlatformRemoteGDBServer::PutFile (const lldb_private::FileSpec& source,
return Platform::PutFile(source,destination,uid,gid);
}
+Error
+PlatformRemoteGDBServer::CreateSymlink (const char *src, // The name of the link is in src
+ const char *dst) // The symlink points to dst
+{
+ Error error = m_gdb_client.CreateSymlink (src, dst);
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+ if (log)
+ log->Printf ("PlatformRemoteGDBServer::CreateSymlink(src='%s', dst='%s') error = %u (%s)", src, dst, error.GetError(), error.AsCString());
+ return error;
+}
+
+Error
+PlatformRemoteGDBServer::Unlink (const char *path)
+{
+ Error error = m_gdb_client.Unlink (path);
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
+ if (log)
+ log->Printf ("PlatformRemoteGDBServer::Unlink(path='%s') error = %u (%s)", path, error.GetError(), error.AsCString());
+ return error;
+}
+
bool
PlatformRemoteGDBServer::GetFileExists (const lldb_private::FileSpec& file_spec)
{
OpenPOWER on IntegriCloud