|
|
|
|
@@ -96,7 +96,8 @@ bool PlatformRemoteGDBServer::GetModuleSpec(const FileSpec &module_file_spec,
|
|
|
|
|
|
|
|
|
|
const auto module_path = module_file_spec.GetPath(false);
|
|
|
|
|
|
|
|
|
|
if (!m_gdb_client.GetModuleInfo(module_file_spec, arch, module_spec)) {
|
|
|
|
|
if (!m_gdb_client_up ||
|
|
|
|
|
!m_gdb_client_up->GetModuleInfo(module_file_spec, arch, module_spec)) {
|
|
|
|
|
LLDB_LOGF(
|
|
|
|
|
log,
|
|
|
|
|
"PlatformRemoteGDBServer::%s - failed to get module info for %s:%s",
|
|
|
|
|
@@ -127,11 +128,7 @@ Status PlatformRemoteGDBServer::GetFileWithUUID(const FileSpec &platform_file,
|
|
|
|
|
|
|
|
|
|
/// Default Constructor
|
|
|
|
|
PlatformRemoteGDBServer::PlatformRemoteGDBServer()
|
|
|
|
|
: Platform(false), // This is a remote platform
|
|
|
|
|
m_gdb_client() {
|
|
|
|
|
m_gdb_client.SetPacketTimeout(
|
|
|
|
|
process_gdb_remote::ProcessGDBRemote::GetPacketTimeout());
|
|
|
|
|
}
|
|
|
|
|
: Platform(/*is_host=*/false) {}
|
|
|
|
|
|
|
|
|
|
/// Destructor.
|
|
|
|
|
///
|
|
|
|
|
@@ -147,29 +144,36 @@ size_t PlatformRemoteGDBServer::GetSoftwareBreakpointTrapOpcode(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool PlatformRemoteGDBServer::GetRemoteOSVersion() {
|
|
|
|
|
m_os_version = m_gdb_client.GetOSVersion();
|
|
|
|
|
if (m_gdb_client_up)
|
|
|
|
|
m_os_version = m_gdb_client_up->GetOSVersion();
|
|
|
|
|
return !m_os_version.empty();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
llvm::Optional<std::string> PlatformRemoteGDBServer::GetRemoteOSBuildString() {
|
|
|
|
|
return m_gdb_client.GetOSBuildString();
|
|
|
|
|
if (!m_gdb_client_up)
|
|
|
|
|
return llvm::None;
|
|
|
|
|
return m_gdb_client_up->GetOSBuildString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
llvm::Optional<std::string>
|
|
|
|
|
PlatformRemoteGDBServer::GetRemoteOSKernelDescription() {
|
|
|
|
|
return m_gdb_client.GetOSKernelDescription();
|
|
|
|
|
if (!m_gdb_client_up)
|
|
|
|
|
return llvm::None;
|
|
|
|
|
return m_gdb_client_up->GetOSKernelDescription();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Remote Platform subclasses need to override this function
|
|
|
|
|
ArchSpec PlatformRemoteGDBServer::GetRemoteSystemArchitecture() {
|
|
|
|
|
return m_gdb_client.GetSystemArchitecture();
|
|
|
|
|
if (!m_gdb_client_up)
|
|
|
|
|
return ArchSpec();
|
|
|
|
|
return m_gdb_client_up->GetSystemArchitecture();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FileSpec PlatformRemoteGDBServer::GetRemoteWorkingDirectory() {
|
|
|
|
|
if (IsConnected()) {
|
|
|
|
|
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
|
|
|
|
|
FileSpec working_dir;
|
|
|
|
|
if (m_gdb_client.GetWorkingDir(working_dir) && log)
|
|
|
|
|
if (m_gdb_client_up->GetWorkingDir(working_dir) && log)
|
|
|
|
|
LLDB_LOGF(log,
|
|
|
|
|
"PlatformRemoteGDBServer::GetRemoteWorkingDirectory() -> '%s'",
|
|
|
|
|
working_dir.GetCString());
|
|
|
|
|
@@ -187,13 +191,17 @@ bool PlatformRemoteGDBServer::SetRemoteWorkingDirectory(
|
|
|
|
|
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
|
|
|
|
|
LLDB_LOGF(log, "PlatformRemoteGDBServer::SetRemoteWorkingDirectory('%s')",
|
|
|
|
|
working_dir.GetCString());
|
|
|
|
|
return m_gdb_client.SetWorkingDir(working_dir) == 0;
|
|
|
|
|
return m_gdb_client_up->SetWorkingDir(working_dir) == 0;
|
|
|
|
|
} else
|
|
|
|
|
return Platform::SetRemoteWorkingDirectory(working_dir);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool PlatformRemoteGDBServer::IsConnected() const {
|
|
|
|
|
return m_gdb_client.IsConnected();
|
|
|
|
|
if (m_gdb_client_up) {
|
|
|
|
|
assert(m_gdb_client_up->IsConnected());
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Status PlatformRemoteGDBServer::ConnectRemote(Args &args) {
|
|
|
|
|
@@ -224,26 +232,31 @@ Status PlatformRemoteGDBServer::ConnectRemote(Args &args) {
|
|
|
|
|
m_platform_scheme = parsed_url->scheme.str();
|
|
|
|
|
m_platform_hostname = parsed_url->hostname.str();
|
|
|
|
|
|
|
|
|
|
m_gdb_client.SetConnection(std::make_unique<ConnectionFileDescriptor>());
|
|
|
|
|
auto client_up =
|
|
|
|
|
std::make_unique<process_gdb_remote::GDBRemoteCommunicationClient>();
|
|
|
|
|
client_up->SetPacketTimeout(
|
|
|
|
|
process_gdb_remote::ProcessGDBRemote::GetPacketTimeout());
|
|
|
|
|
client_up->SetConnection(std::make_unique<ConnectionFileDescriptor>());
|
|
|
|
|
if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) {
|
|
|
|
|
repro::GDBRemoteProvider &provider =
|
|
|
|
|
g->GetOrCreate<repro::GDBRemoteProvider>();
|
|
|
|
|
m_gdb_client.SetPacketRecorder(provider.GetNewPacketRecorder());
|
|
|
|
|
client_up->SetPacketRecorder(provider.GetNewPacketRecorder());
|
|
|
|
|
}
|
|
|
|
|
m_gdb_client.Connect(url, &error);
|
|
|
|
|
client_up->Connect(url, &error);
|
|
|
|
|
|
|
|
|
|
if (error.Fail())
|
|
|
|
|
return error;
|
|
|
|
|
|
|
|
|
|
if (m_gdb_client.HandshakeWithServer(&error)) {
|
|
|
|
|
m_gdb_client.GetHostInfo();
|
|
|
|
|
if (client_up->HandshakeWithServer(&error)) {
|
|
|
|
|
m_gdb_client_up = std::move(client_up);
|
|
|
|
|
m_gdb_client_up->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);
|
|
|
|
|
m_gdb_client_up->SetWorkingDir(m_working_dir);
|
|
|
|
|
|
|
|
|
|
m_supported_architectures.clear();
|
|
|
|
|
ArchSpec remote_arch = m_gdb_client.GetSystemArchitecture();
|
|
|
|
|
ArchSpec remote_arch = m_gdb_client_up->GetSystemArchitecture();
|
|
|
|
|
if (remote_arch) {
|
|
|
|
|
m_supported_architectures.push_back(remote_arch);
|
|
|
|
|
if (remote_arch.GetTriple().isArch64Bit())
|
|
|
|
|
@@ -251,7 +264,7 @@ Status PlatformRemoteGDBServer::ConnectRemote(Args &args) {
|
|
|
|
|
ArchSpec(remote_arch.GetTriple().get32BitArchVariant()));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
m_gdb_client.Disconnect();
|
|
|
|
|
client_up->Disconnect();
|
|
|
|
|
if (error.Success())
|
|
|
|
|
error.SetErrorString("handshake failed");
|
|
|
|
|
}
|
|
|
|
|
@@ -260,13 +273,14 @@ Status PlatformRemoteGDBServer::ConnectRemote(Args &args) {
|
|
|
|
|
|
|
|
|
|
Status PlatformRemoteGDBServer::DisconnectRemote() {
|
|
|
|
|
Status error;
|
|
|
|
|
m_gdb_client.Disconnect(&error);
|
|
|
|
|
m_gdb_client_up.reset();
|
|
|
|
|
m_remote_signals_sp.reset();
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *PlatformRemoteGDBServer::GetHostname() {
|
|
|
|
|
m_gdb_client.GetHostname(m_name);
|
|
|
|
|
if (m_gdb_client_up)
|
|
|
|
|
m_gdb_client_up->GetHostname(m_name);
|
|
|
|
|
if (m_name.empty())
|
|
|
|
|
return nullptr;
|
|
|
|
|
return m_name.c_str();
|
|
|
|
|
@@ -275,7 +289,7 @@ const char *PlatformRemoteGDBServer::GetHostname() {
|
|
|
|
|
llvm::Optional<std::string>
|
|
|
|
|
PlatformRemoteGDBServer::DoGetUserName(UserIDResolver::id_t uid) {
|
|
|
|
|
std::string name;
|
|
|
|
|
if (m_gdb_client.GetUserName(uid, name))
|
|
|
|
|
if (m_gdb_client_up && m_gdb_client_up->GetUserName(uid, name))
|
|
|
|
|
return std::move(name);
|
|
|
|
|
return llvm::None;
|
|
|
|
|
}
|
|
|
|
|
@@ -283,7 +297,7 @@ PlatformRemoteGDBServer::DoGetUserName(UserIDResolver::id_t uid) {
|
|
|
|
|
llvm::Optional<std::string>
|
|
|
|
|
PlatformRemoteGDBServer::DoGetGroupName(UserIDResolver::id_t gid) {
|
|
|
|
|
std::string name;
|
|
|
|
|
if (m_gdb_client.GetGroupName(gid, name))
|
|
|
|
|
if (m_gdb_client_up && m_gdb_client_up->GetGroupName(gid, name))
|
|
|
|
|
return std::move(name);
|
|
|
|
|
return llvm::None;
|
|
|
|
|
}
|
|
|
|
|
@@ -291,12 +305,16 @@ PlatformRemoteGDBServer::DoGetGroupName(UserIDResolver::id_t gid) {
|
|
|
|
|
uint32_t PlatformRemoteGDBServer::FindProcesses(
|
|
|
|
|
const ProcessInstanceInfoMatch &match_info,
|
|
|
|
|
ProcessInstanceInfoList &process_infos) {
|
|
|
|
|
return m_gdb_client.FindProcesses(match_info, process_infos);
|
|
|
|
|
if (m_gdb_client_up)
|
|
|
|
|
return m_gdb_client_up->FindProcesses(match_info, process_infos);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool PlatformRemoteGDBServer::GetProcessInfo(
|
|
|
|
|
lldb::pid_t pid, ProcessInstanceInfo &process_info) {
|
|
|
|
|
return m_gdb_client.GetProcessInfo(pid, process_info);
|
|
|
|
|
if (m_gdb_client_up)
|
|
|
|
|
return m_gdb_client_up->GetProcessInfo(pid, process_info);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Status PlatformRemoteGDBServer::LaunchProcess(ProcessLaunchInfo &launch_info) {
|
|
|
|
|
@@ -305,6 +323,8 @@ Status PlatformRemoteGDBServer::LaunchProcess(ProcessLaunchInfo &launch_info) {
|
|
|
|
|
|
|
|
|
|
LLDB_LOGF(log, "PlatformRemoteGDBServer::%s() called", __FUNCTION__);
|
|
|
|
|
|
|
|
|
|
if (!IsConnected())
|
|
|
|
|
return Status("Not connected.");
|
|
|
|
|
auto num_file_actions = launch_info.GetNumFileActions();
|
|
|
|
|
for (decltype(num_file_actions) i = 0; i < num_file_actions; ++i) {
|
|
|
|
|
const auto file_action = launch_info.GetFileActionAtIndex(i);
|
|
|
|
|
@@ -312,34 +332,34 @@ Status PlatformRemoteGDBServer::LaunchProcess(ProcessLaunchInfo &launch_info) {
|
|
|
|
|
continue;
|
|
|
|
|
switch (file_action->GetFD()) {
|
|
|
|
|
case STDIN_FILENO:
|
|
|
|
|
m_gdb_client.SetSTDIN(file_action->GetFileSpec());
|
|
|
|
|
m_gdb_client_up->SetSTDIN(file_action->GetFileSpec());
|
|
|
|
|
break;
|
|
|
|
|
case STDOUT_FILENO:
|
|
|
|
|
m_gdb_client.SetSTDOUT(file_action->GetFileSpec());
|
|
|
|
|
m_gdb_client_up->SetSTDOUT(file_action->GetFileSpec());
|
|
|
|
|
break;
|
|
|
|
|
case STDERR_FILENO:
|
|
|
|
|
m_gdb_client.SetSTDERR(file_action->GetFileSpec());
|
|
|
|
|
m_gdb_client_up->SetSTDERR(file_action->GetFileSpec());
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_gdb_client.SetDisableASLR(
|
|
|
|
|
m_gdb_client_up->SetDisableASLR(
|
|
|
|
|
launch_info.GetFlags().Test(eLaunchFlagDisableASLR));
|
|
|
|
|
m_gdb_client.SetDetachOnError(
|
|
|
|
|
m_gdb_client_up->SetDetachOnError(
|
|
|
|
|
launch_info.GetFlags().Test(eLaunchFlagDetachOnError));
|
|
|
|
|
|
|
|
|
|
FileSpec working_dir = launch_info.GetWorkingDirectory();
|
|
|
|
|
if (working_dir) {
|
|
|
|
|
m_gdb_client.SetWorkingDir(working_dir);
|
|
|
|
|
m_gdb_client_up->SetWorkingDir(working_dir);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Send the environment and the program + arguments after we connect
|
|
|
|
|
m_gdb_client.SendEnvironment(launch_info.GetEnvironment());
|
|
|
|
|
m_gdb_client_up->SendEnvironment(launch_info.GetEnvironment());
|
|
|
|
|
|
|
|
|
|
ArchSpec arch_spec = launch_info.GetArchitecture();
|
|
|
|
|
const char *arch_triple = arch_spec.GetTriple().str().c_str();
|
|
|
|
|
|
|
|
|
|
m_gdb_client.SendLaunchArchPacket(arch_triple);
|
|
|
|
|
m_gdb_client_up->SendLaunchArchPacket(arch_triple);
|
|
|
|
|
LLDB_LOGF(
|
|
|
|
|
log,
|
|
|
|
|
"PlatformRemoteGDBServer::%s() set launch architecture triple to '%s'",
|
|
|
|
|
@@ -349,14 +369,14 @@ Status PlatformRemoteGDBServer::LaunchProcess(ProcessLaunchInfo &launch_info) {
|
|
|
|
|
{
|
|
|
|
|
// Scope for the scoped timeout object
|
|
|
|
|
process_gdb_remote::GDBRemoteCommunication::ScopedTimeout timeout(
|
|
|
|
|
m_gdb_client, std::chrono::seconds(5));
|
|
|
|
|
arg_packet_err = m_gdb_client.SendArgumentsPacket(launch_info);
|
|
|
|
|
*m_gdb_client_up, std::chrono::seconds(5));
|
|
|
|
|
arg_packet_err = m_gdb_client_up->SendArgumentsPacket(launch_info);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (arg_packet_err == 0) {
|
|
|
|
|
std::string error_str;
|
|
|
|
|
if (m_gdb_client.GetLaunchSuccess(error_str)) {
|
|
|
|
|
const auto pid = m_gdb_client.GetCurrentProcessID(false);
|
|
|
|
|
if (m_gdb_client_up->GetLaunchSuccess(error_str)) {
|
|
|
|
|
const auto pid = m_gdb_client_up->GetCurrentProcessID(false);
|
|
|
|
|
if (pid != LLDB_INVALID_PROCESS_ID) {
|
|
|
|
|
launch_info.SetProcessID(pid);
|
|
|
|
|
LLDB_LOGF(log,
|
|
|
|
|
@@ -428,6 +448,8 @@ PlatformRemoteGDBServer::DebugProcess(ProcessLaunchInfo &launch_info,
|
|
|
|
|
|
|
|
|
|
bool PlatformRemoteGDBServer::LaunchGDBServer(lldb::pid_t &pid,
|
|
|
|
|
std::string &connect_url) {
|
|
|
|
|
assert(IsConnected());
|
|
|
|
|
|
|
|
|
|
ArchSpec remote_arch = GetRemoteSystemArchitecture();
|
|
|
|
|
llvm::Triple &remote_triple = remote_arch.GetTriple();
|
|
|
|
|
|
|
|
|
|
@@ -440,11 +462,11 @@ bool PlatformRemoteGDBServer::LaunchGDBServer(lldb::pid_t &pid,
|
|
|
|
|
// localhost, so we will need the remote debugserver to accept connections
|
|
|
|
|
// only from localhost, no matter what our current hostname is
|
|
|
|
|
launch_result =
|
|
|
|
|
m_gdb_client.LaunchGDBServer("127.0.0.1", pid, port, socket_name);
|
|
|
|
|
m_gdb_client_up->LaunchGDBServer("127.0.0.1", pid, port, socket_name);
|
|
|
|
|
} else {
|
|
|
|
|
// All other hosts should use their actual hostname
|
|
|
|
|
launch_result =
|
|
|
|
|
m_gdb_client.LaunchGDBServer(nullptr, pid, port, socket_name);
|
|
|
|
|
m_gdb_client_up->LaunchGDBServer(nullptr, pid, port, socket_name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!launch_result)
|
|
|
|
|
@@ -457,7 +479,8 @@ bool PlatformRemoteGDBServer::LaunchGDBServer(lldb::pid_t &pid,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool PlatformRemoteGDBServer::KillSpawnedProcess(lldb::pid_t pid) {
|
|
|
|
|
return m_gdb_client.KillSpawnedProcess(pid);
|
|
|
|
|
assert(IsConnected());
|
|
|
|
|
return m_gdb_client_up->KillSpawnedProcess(pid);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lldb::ProcessSP PlatformRemoteGDBServer::Attach(
|
|
|
|
|
@@ -513,7 +536,9 @@ lldb::ProcessSP PlatformRemoteGDBServer::Attach(
|
|
|
|
|
|
|
|
|
|
Status PlatformRemoteGDBServer::MakeDirectory(const FileSpec &file_spec,
|
|
|
|
|
uint32_t mode) {
|
|
|
|
|
Status error = m_gdb_client.MakeDirectory(file_spec, mode);
|
|
|
|
|
if (!IsConnected())
|
|
|
|
|
return Status("Not connected.");
|
|
|
|
|
Status error = m_gdb_client_up->MakeDirectory(file_spec, mode);
|
|
|
|
|
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
|
|
|
|
|
LLDB_LOGF(log,
|
|
|
|
|
"PlatformRemoteGDBServer::MakeDirectory(path='%s', mode=%o) "
|
|
|
|
|
@@ -524,7 +549,10 @@ Status PlatformRemoteGDBServer::MakeDirectory(const FileSpec &file_spec,
|
|
|
|
|
|
|
|
|
|
Status PlatformRemoteGDBServer::GetFilePermissions(const FileSpec &file_spec,
|
|
|
|
|
uint32_t &file_permissions) {
|
|
|
|
|
Status error = m_gdb_client.GetFilePermissions(file_spec, file_permissions);
|
|
|
|
|
if (!IsConnected())
|
|
|
|
|
return Status("Not connected.");
|
|
|
|
|
Status error =
|
|
|
|
|
m_gdb_client_up->GetFilePermissions(file_spec, file_permissions);
|
|
|
|
|
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
|
|
|
|
|
LLDB_LOGF(log,
|
|
|
|
|
"PlatformRemoteGDBServer::GetFilePermissions(path='%s', "
|
|
|
|
|
@@ -536,7 +564,10 @@ Status PlatformRemoteGDBServer::GetFilePermissions(const FileSpec &file_spec,
|
|
|
|
|
|
|
|
|
|
Status PlatformRemoteGDBServer::SetFilePermissions(const FileSpec &file_spec,
|
|
|
|
|
uint32_t file_permissions) {
|
|
|
|
|
Status error = m_gdb_client.SetFilePermissions(file_spec, file_permissions);
|
|
|
|
|
if (!IsConnected())
|
|
|
|
|
return Status("Not connected.");
|
|
|
|
|
Status error =
|
|
|
|
|
m_gdb_client_up->SetFilePermissions(file_spec, file_permissions);
|
|
|
|
|
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
|
|
|
|
|
LLDB_LOGF(log,
|
|
|
|
|
"PlatformRemoteGDBServer::SetFilePermissions(path='%s', "
|
|
|
|
|
@@ -550,33 +581,47 @@ lldb::user_id_t PlatformRemoteGDBServer::OpenFile(const FileSpec &file_spec,
|
|
|
|
|
File::OpenOptions flags,
|
|
|
|
|
uint32_t mode,
|
|
|
|
|
Status &error) {
|
|
|
|
|
return m_gdb_client.OpenFile(file_spec, flags, mode, error);
|
|
|
|
|
if (IsConnected())
|
|
|
|
|
return m_gdb_client_up->OpenFile(file_spec, flags, mode, error);
|
|
|
|
|
return LLDB_INVALID_UID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool PlatformRemoteGDBServer::CloseFile(lldb::user_id_t fd, Status &error) {
|
|
|
|
|
return m_gdb_client.CloseFile(fd, error);
|
|
|
|
|
if (IsConnected())
|
|
|
|
|
return m_gdb_client_up->CloseFile(fd, error);
|
|
|
|
|
error = Status("Not connected.");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lldb::user_id_t
|
|
|
|
|
PlatformRemoteGDBServer::GetFileSize(const FileSpec &file_spec) {
|
|
|
|
|
return m_gdb_client.GetFileSize(file_spec);
|
|
|
|
|
if (IsConnected())
|
|
|
|
|
return m_gdb_client_up->GetFileSize(file_spec);
|
|
|
|
|
return LLDB_INVALID_UID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PlatformRemoteGDBServer::AutoCompleteDiskFileOrDirectory(
|
|
|
|
|
CompletionRequest &request, bool only_dir) {
|
|
|
|
|
m_gdb_client.AutoCompleteDiskFileOrDirectory(request, only_dir);
|
|
|
|
|
if (IsConnected())
|
|
|
|
|
m_gdb_client_up->AutoCompleteDiskFileOrDirectory(request, only_dir);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint64_t PlatformRemoteGDBServer::ReadFile(lldb::user_id_t fd, uint64_t offset,
|
|
|
|
|
void *dst, uint64_t dst_len,
|
|
|
|
|
Status &error) {
|
|
|
|
|
return m_gdb_client.ReadFile(fd, offset, dst, dst_len, error);
|
|
|
|
|
if (IsConnected())
|
|
|
|
|
return m_gdb_client_up->ReadFile(fd, offset, dst, dst_len, error);
|
|
|
|
|
error = Status("Not connected.");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint64_t PlatformRemoteGDBServer::WriteFile(lldb::user_id_t fd, uint64_t offset,
|
|
|
|
|
const void *src, uint64_t src_len,
|
|
|
|
|
Status &error) {
|
|
|
|
|
return m_gdb_client.WriteFile(fd, offset, src, src_len, error);
|
|
|
|
|
if (IsConnected())
|
|
|
|
|
return m_gdb_client_up->WriteFile(fd, offset, src, src_len, error);
|
|
|
|
|
error = Status("Not connected.");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Status PlatformRemoteGDBServer::PutFile(const FileSpec &source,
|
|
|
|
|
@@ -589,7 +634,9 @@ Status PlatformRemoteGDBServer::CreateSymlink(
|
|
|
|
|
const FileSpec &src, // The name of the link is in src
|
|
|
|
|
const FileSpec &dst) // The symlink points to dst
|
|
|
|
|
{
|
|
|
|
|
Status error = m_gdb_client.CreateSymlink(src, dst);
|
|
|
|
|
if (!IsConnected())
|
|
|
|
|
return Status("Not connected.");
|
|
|
|
|
Status error = m_gdb_client_up->CreateSymlink(src, dst);
|
|
|
|
|
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
|
|
|
|
|
LLDB_LOGF(log,
|
|
|
|
|
"PlatformRemoteGDBServer::CreateSymlink(src='%s', dst='%s') "
|
|
|
|
|
@@ -600,7 +647,9 @@ Status PlatformRemoteGDBServer::CreateSymlink(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Status PlatformRemoteGDBServer::Unlink(const FileSpec &file_spec) {
|
|
|
|
|
Status error = m_gdb_client.Unlink(file_spec);
|
|
|
|
|
if (!IsConnected())
|
|
|
|
|
return Status("Not connected.");
|
|
|
|
|
Status error = m_gdb_client_up->Unlink(file_spec);
|
|
|
|
|
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
|
|
|
|
|
LLDB_LOGF(log, "PlatformRemoteGDBServer::Unlink(path='%s') error = %u (%s)",
|
|
|
|
|
file_spec.GetCString(), error.GetError(), error.AsCString());
|
|
|
|
|
@@ -608,7 +657,9 @@ Status PlatformRemoteGDBServer::Unlink(const FileSpec &file_spec) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool PlatformRemoteGDBServer::GetFileExists(const FileSpec &file_spec) {
|
|
|
|
|
return m_gdb_client.GetFileExists(file_spec);
|
|
|
|
|
if (IsConnected())
|
|
|
|
|
return m_gdb_client_up->GetFileExists(file_spec);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Status PlatformRemoteGDBServer::RunShellCommand(
|
|
|
|
|
@@ -621,8 +672,10 @@ Status PlatformRemoteGDBServer::RunShellCommand(
|
|
|
|
|
std::string
|
|
|
|
|
*command_output, // Pass NULL if you don't want the command output
|
|
|
|
|
const Timeout<std::micro> &timeout) {
|
|
|
|
|
return m_gdb_client.RunShellCommand(command, working_dir, status_ptr,
|
|
|
|
|
signo_ptr, command_output, timeout);
|
|
|
|
|
if (!IsConnected())
|
|
|
|
|
return Status("Not connected.");
|
|
|
|
|
return m_gdb_client_up->RunShellCommand(command, working_dir, status_ptr,
|
|
|
|
|
signo_ptr, command_output, timeout);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PlatformRemoteGDBServer::CalculateTrapHandlerSymbolNames() {
|
|
|
|
|
@@ -642,7 +695,7 @@ const UnixSignalsSP &PlatformRemoteGDBServer::GetRemoteUnixSignals() {
|
|
|
|
|
|
|
|
|
|
StringExtractorGDBRemote response;
|
|
|
|
|
auto result =
|
|
|
|
|
m_gdb_client.SendPacketAndWaitForResponse("jSignalsInfo", response);
|
|
|
|
|
m_gdb_client_up->SendPacketAndWaitForResponse("jSignalsInfo", response);
|
|
|
|
|
|
|
|
|
|
if (result != decltype(result)::Success ||
|
|
|
|
|
response.GetResponseType() != response.eResponse)
|
|
|
|
|
@@ -754,7 +807,9 @@ size_t PlatformRemoteGDBServer::ConnectToWaitingProcesses(Debugger &debugger,
|
|
|
|
|
size_t PlatformRemoteGDBServer::GetPendingGdbServerList(
|
|
|
|
|
std::vector<std::string> &connection_urls) {
|
|
|
|
|
std::vector<std::pair<uint16_t, std::string>> remote_servers;
|
|
|
|
|
m_gdb_client.QueryGDBServer(remote_servers);
|
|
|
|
|
if (!IsConnected())
|
|
|
|
|
return 0;
|
|
|
|
|
m_gdb_client_up->QueryGDBServer(remote_servers);
|
|
|
|
|
for (const auto &gdbserver : remote_servers) {
|
|
|
|
|
const char *socket_name_cstr =
|
|
|
|
|
gdbserver.second.empty() ? nullptr : gdbserver.second.c_str();
|
|
|
|
|
|