10#include "lldb/Host/Config.h"
31#include "llvm/ADT/StringSet.h"
32#include "llvm/Support/FormatAdapters.h"
85 return "A platform that uses the GDB remote protocol as the communication "
106 const auto module_path = module_file_spec.
GetPath(
false);
109 !
m_gdb_client_up->GetModuleInfo(module_file_spec, arch, module_spec)) {
112 "PlatformRemoteGDBServer::%s - failed to get module info for %s:%s",
113 __FUNCTION__, module_path.c_str(),
120 module_spec.
Dump(stream);
122 "PlatformRemoteGDBServer::%s - got module info for (%s:%s) : %s",
123 __FUNCTION__, module_path.c_str(),
131 const UUID *uuid_ptr,
134 local_file = platform_file;
167std::optional<std::string>
187 "PlatformRemoteGDBServer::GetRemoteWorkingDirectory() -> '%s'",
188 working_dir.
GetPath().c_str());
201 LLDB_LOGF(log,
"PlatformRemoteGDBServer::SetRemoteWorkingDirectory('%s')",
202 working_dir.
GetPath().c_str());
219 error.SetErrorStringWithFormat(
"the platform is already connected to '%s', "
220 "execute 'platform disconnect' to close the "
221 "current connection",
227 error.SetErrorString(
228 "\"platform connect\" takes a single argument: <connect-url>");
234 return Status(
"URL is null.");
236 std::optional<URI> parsed_url =
URI::Parse(url);
238 return Status(
"Invalid URL: %s", url);
245 std::make_unique<process_gdb_remote::GDBRemoteCommunicationClient>();
246 client_up->SetPacketTimeout(
248 client_up->SetConnection(std::make_unique<ConnectionFileDescriptor>());
249 client_up->Connect(url, &
error);
254 if (client_up->HandshakeWithServer(&
error)) {
266 if (remote_arch.
GetTriple().isArch64Bit())
271 client_up->Disconnect();
273 error.SetErrorString(
"handshake failed");
293std::optional<std::string>
297 return std::move(name);
301std::optional<std::string>
305 return std::move(name);
328 LLDB_LOGF(log,
"PlatformRemoteGDBServer::%s() called", __FUNCTION__);
331 return Status(
"Not connected.");
333 for (
decltype(num_file_actions) i = 0; i < num_file_actions; ++i) {
337 switch (file_action->GetFD()) {
364 const char *arch_triple = arch_spec.
GetTriple().str().c_str();
369 "PlatformRemoteGDBServer::%s() set launch architecture triple to '%s'",
370 __FUNCTION__, arch_triple ? arch_triple :
"<NULL>");
382 error.SetErrorStringWithFormatv(
"Cannot launch '{0}': {1}",
384 llvm::fmt_consume(std::move(err)));
393 "PlatformRemoteGDBServer::%s() pid %" PRIu64
394 " launched successfully",
398 "PlatformRemoteGDBServer::%s() launch succeeded but we "
399 "didn't get a valid process id back!",
401 error.SetErrorString(
"failed to get PID");
408 return Status(
"failed to kill remote spawned process");
420 std::string connect_url;
422 error.SetErrorStringWithFormat(
"unable to launch a GDB server on '%s'",
428 "gdb-remote",
nullptr,
true);
434 error = process_sp->ConnectRemote(connect_url.c_str());
437 error = process_sp->ConnectRemote(connect_url.c_str());
439 error = process_sp->Launch(launch_info);
441 printf(
"error: connect remote failed (%s)\n",
error.AsCString());
447 error.SetErrorString(
"not connected to remote gdb server");
454 std::string &connect_url) {
458 llvm::Triple &remote_triple = remote_arch.
GetTriple();
461 std::string socket_name;
462 bool launch_result =
false;
463 if (remote_triple.getVendor() == llvm::Triple::Apple &&
464 remote_triple.getOS() == llvm::Triple::IOS) {
481 (socket_name.empty()) ?
nullptr : socket_name.c_str());
499 std::string connect_url;
501 error.SetErrorStringWithFormat(
"unable to launch a GDB server on '%s'",
504 if (target ==
nullptr) {
509 target = new_target_sp.get();
513 if (target &&
error.Success()) {
518 "gdb-remote",
nullptr,
true);
520 error = process_sp->ConnectRemote(connect_url.c_str());
521 if (
error.Success()) {
524 process_sp->HijackProcessEvents(listener_sp);
526 error = process_sp->Attach(attach_info);
536 error.SetErrorString(
"not connected to remote gdb server");
545 return Status(
"Not connected.");
549 "PlatformRemoteGDBServer::MakeDirectory(path='%s', mode=%o) "
557 uint32_t &file_permissions) {
559 return Status(
"Not connected.");
564 "PlatformRemoteGDBServer::GetFilePermissions(path='%s', "
565 "file_permissions=%o) error = %u (%s)",
566 file_spec.
GetPath().c_str(), file_permissions,
error.GetError(),
572 uint32_t file_permissions) {
574 return Status(
"Not connected.");
579 "PlatformRemoteGDBServer::SetFilePermissions(path='%s', "
580 "file_permissions=%o) error = %u (%s)",
581 file_spec.
GetPath().c_str(), file_permissions,
error.GetError(),
616 void *dst, uint64_t dst_len,
625 const void *src, uint64_t src_len,
635 uint32_t uid, uint32_t gid) {
644 return Status(
"Not connected.");
648 "PlatformRemoteGDBServer::CreateSymlink(src='%s', dst='%s') "
657 return Status(
"Not connected.");
660 LLDB_LOGF(log,
"PlatformRemoteGDBServer::Unlink(path='%s') error = %u (%s)",
672 llvm::StringRef shell, llvm::StringRef command,
682 return Status(
"Not connected.");
683 return m_gdb_client_up->RunShellCommand(command, working_dir, status_ptr,
684 signo_ptr, command_output, timeout);
687llvm::ErrorOr<llvm::MD5::MD5Result>
690 return std::make_error_code(std::errc::not_connected);
712 m_gdb_client_up->SendPacketAndWaitForResponse(
"jSignalsInfo", response);
714 if (result !=
decltype(result)
::Success ||
719 if (!object_sp || !object_sp->IsValid())
722 auto array_sp = object_sp->GetAsArray();
723 if (!array_sp || !array_sp->IsValid())
726 auto remote_signals_sp = std::make_shared<lldb_private::GDBRemoteSignals>();
728 bool done = array_sp->ForEach(
730 if (!
object || !object->
IsValid())
734 if (!dict || !dict->IsValid())
739 if (!dict->GetValueForKeyAsInteger(
"signo", signo))
742 llvm::StringRef name;
743 if (!dict->GetValueForKeyAsString(
"name", name))
747 bool suppress{false};
749 if (object_sp && object_sp->IsValid())
750 suppress = object_sp->GetBooleanValue();
753 object_sp = dict->GetValueForKey(
"stop");
754 if (object_sp && object_sp->IsValid())
755 stop = object_sp->GetBooleanValue();
758 object_sp = dict->GetValueForKey(
"notify");
759 if (object_sp && object_sp->IsValid())
760 notify = object_sp->GetBooleanValue();
762 std::string description;
763 object_sp = dict->GetValueForKey(
"description");
764 if (object_sp && object_sp->IsValid())
765 description = std::string(object_sp->GetStringValue());
767 llvm::StringRef name_backed, description_backed;
769 std::lock_guard<std::mutex> guard(g_signal_string_mutex);
771 g_signal_string_storage.insert(name).first->getKeyData();
772 if (!description.empty())
774 g_signal_string_storage.insert(description).first->getKeyData();
777 remote_signals_sp->AddSignal(signo, name_backed, suppress, stop, notify,
789 const std::string &platform_scheme,
const std::string &platform_hostname,
790 uint16_t port,
const char *socket_name) {
791 const char *override_scheme =
792 getenv(
"LLDB_PLATFORM_REMOTE_GDB_SERVER_SCHEME");
793 const char *override_hostname =
794 getenv(
"LLDB_PLATFORM_REMOTE_GDB_SERVER_HOSTNAME");
795 const char *port_offset_c_str =
796 getenv(
"LLDB_PLATFORM_REMOTE_GDB_SERVER_PORT_OFFSET");
797 int port_offset = port_offset_c_str ? ::atoi(port_offset_c_str) : 0;
799 return MakeUrl(override_scheme ? override_scheme : platform_scheme.c_str(),
800 override_hostname ? override_hostname
801 : platform_hostname.c_str(),
802 port + port_offset, socket_name);
806 const char *hostname,
807 uint16_t port,
const char *path) {
809 result.
Printf(
"%s://[%s]", scheme, hostname);
811 result.
Printf(
":%u", port);
813 result.
Write(path, strlen(path));
819 std::vector<std::string> connection_urls;
822 for (
size_t i = 0; i < connection_urls.size(); ++i) {
827 return connection_urls.size();
831 std::vector<std::string> &connection_urls) {
832 std::vector<std::pair<uint16_t, std::string>> remote_servers;
836 for (
const auto &gdbserver : remote_servers) {
837 const char *socket_name_cstr =
838 gdbserver.second.empty() ? nullptr : gdbserver.second.c_str();
839 connection_urls.emplace_back(
841 gdbserver.first, socket_name_cstr));
843 return connection_urls.size();
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOGF(log,...)
#define LLDB_PLUGIN_DEFINE_ADV(ClassName, PluginName)
An architecture specification class.
llvm::Triple & GetTriple()
Architecture triple accessor.
bool TripleVendorWasSpecified() const
bool TripleOSWasSpecified() const
A command line argument class.
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
void ReplaceArgumentAtIndex(size_t idx, llvm::StringRef arg_str, char quote_char='\0')
Replaces the argument value at index idx to arg_str if idx is a valid argument index.
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
Class that manages the actual breakpoint that will be inserted into the running program.
"lldb/Utility/ArgCompletionRequest.h"
A uniqued constant string class.
A class to manage flag bits.
TargetList & GetTargetList()
Get accessor for the target list.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
bool Test(ValueType bit) const
Test a single flag bit.
void Dump(Stream &strm) const
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
lldb::ListenerSP GetListenerForProcess(Debugger &debugger)
lldb::ListenerSP GetHijackListener() const
void SetProcessID(lldb::pid_t pid)
FileSpec & GetExecutableFile()
lldb::ListenerSP GetListener() const
lldb::ListenerSP GetShadowListener() const
Environment & GetEnvironment()
ArchSpec & GetArchitecture()
const FileAction * GetFileActionAtIndex(size_t idx) const
const FileSpec & GetWorkingDirectory() const
size_t GetNumFileActions() const
const char * GetData() const
llvm::StringRef GetString() const
size_t Write(const void *src, size_t src_len)
Output character bytes to the stream.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
ObjectSP GetValueForKey(llvm::StringRef key) const
Dictionary * GetAsDictionary()
virtual bool IsValid() const
static ObjectSP ParseJSON(llvm::StringRef json_text)
Status CreateTarget(Debugger &debugger, llvm::StringRef user_exe_path, llvm::StringRef triple_str, LoadDependentFiles get_dependent_modules, const OptionGroupPlatform *platform_options, lldb::TargetSP &target_sp)
Create a new Target.
const lldb::ProcessSP & CreateProcess(lldb::ListenerSP listener_sp, llvm::StringRef plugin_name, const FileSpec *crash_file, bool can_connect)
static lldb::UnixSignalsSP Create(const ArchSpec &arch)
static std::chrono::seconds GetPacketTimeout()
#define LLDB_INVALID_PROCESS_ID
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
std::vector< ProcessInstanceInfo > ProcessInstanceInfoList
std::shared_ptr< lldb_private::UnixSignals > UnixSignalsSP
std::shared_ptr< lldb_private::Platform > PlatformSP
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::Listener > ListenerSP
std::shared_ptr< lldb_private::Target > TargetSP
static std::optional< URI > Parse(llvm::StringRef uri)