From 3f4b4990679a9a322fb7df64e76e93c13b175831 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Sat, 25 Jan 2025 22:37:34 +1300 Subject: [PATCH] Handle various LLDB protocol extensions only if we know we're talking to LLDB. Then if GDB implements any of these extensions in an incompatible way, we won't be broken. --- src/GdbServerConnection.cc | 39 ++++++++++++++++++++++++++------------ src/GdbServerConnection.h | 1 + 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/GdbServerConnection.cc b/src/GdbServerConnection.cc index abd72389675..8668cad9ebb 100644 --- a/src/GdbServerConnection.cc +++ b/src/GdbServerConnection.cc @@ -831,7 +831,8 @@ bool GdbServerConnection::query(char* payload) { write_packet(""); return false; } - if (!strcmp(name, "MemoryRegionInfo") && args) { + if (!strcmp(name, "MemoryRegionInfo") && args && + debugger_type == DebuggerType::LLDB) { req = GdbRequest(DREQ_MEM_INFO); req.target = query_thread; req.mem().addr = strtoul(args, &args, 16); @@ -849,7 +850,7 @@ bool GdbServerConnection::query(char* payload) { write_packet(""); return false; } - if (!strcmp(name, "HostInfo")) { + if (!strcmp(name, "HostInfo") && debugger_type == DebuggerType::LLDB) { // lldb-server sends a reply like // triple:7838365f36342d2d6c696e75782d676e75;ptrsize:8;distribution_id:6665646f7261; // watchpoint_exceptions_received:after;endian:little;os_version:6.6.13; @@ -860,12 +861,12 @@ bool GdbServerConnection::query(char* payload) { write_packet(""); return false; } - if (!strcmp(name, "VAttachOrWaitSupported")) { + if (!strcmp(name, "VAttachOrWaitSupported") && debugger_type == DebuggerType::LLDB) { // We don't handle vAttach and variants. write_packet(""); return false; } - if (!strcmp(name, "ProcessInfo")) { + if (!strcmp(name, "ProcessInfo") && debugger_type == DebuggerType::LLDB) { // lldb-server sends a reply like // pid:3663df;parent-pid:3663de;real-uid:3e8;real-gid:3e8;effective-uid:3e8;effective-gid:3e8; // triple:7838365f36342d2d6c696e75782d676e75;ostype:linux;endian:little;ptrsize:8 @@ -874,12 +875,12 @@ bool GdbServerConnection::query(char* payload) { write_packet(""); return false; } - if (!strcmp(name, "StructuredDataPlugins")) { + if (!strcmp(name, "StructuredDataPlugins") && debugger_type == DebuggerType::LLDB) { // This isn't documented and lldb-server doesn't support it write_packet(""); return false; } - if (!strcmp(name, "ShlibInfoAddr")) { + if (!strcmp(name, "ShlibInfoAddr") && debugger_type == DebuggerType::LLDB) { // This isn't documented and lldb-server doesn't seem to support it write_packet(""); return false; @@ -890,7 +891,10 @@ bool GdbServerConnection::query(char* payload) { } // LLDB QThreadSuffixSupported extension -static void parse_thread_suffix_threadid(char* payload, GdbThreadId* out) { +void GdbServerConnection::parse_thread_suffix_threadid(char* payload, GdbThreadId* out) { + if (debugger_type != DebuggerType::LLDB) { + return; + } char* semicolon = strrchr(payload, ';'); if (!semicolon) { return; @@ -947,27 +951,32 @@ bool GdbServerConnection::set_var(char* payload) { write_packet("OK"); return false; } - if (!strcmp(name, "ListThreadsInStopReply")) { + if (!strcmp(name, "ListThreadsInStopReply") && + debugger_type == DebuggerType::LLDB) { write_packet("OK"); list_threads_in_stop_reply_ = true; return false; } - if (!strcmp(name, "ThreadSuffixSupported")) { + if (!strcmp(name, "ThreadSuffixSupported") && + debugger_type == DebuggerType::LLDB) { write_packet("OK"); return false; } - if (!strcmp(name, "EnableErrorStrings")) { + if (!strcmp(name, "EnableErrorStrings") && + debugger_type == DebuggerType::LLDB) { // We don't support human-readable error strings. write_packet(""); return false; } - if (!strcmp(name, "SaveRegisterState")) { + if (!strcmp(name, "SaveRegisterState") && + debugger_type == DebuggerType::LLDB) { req = GdbRequest(DREQ_SAVE_REGISTER_STATE); req.target = target; return true; } - if (!strcmp(name, "RestoreRegisterState")) { + if (!strcmp(name, "RestoreRegisterState") && + debugger_type == DebuggerType::LLDB) { req = GdbRequest(DREQ_RESTORE_REGISTER_STATE); req.target = target; char* end; @@ -985,6 +994,9 @@ bool GdbServerConnection::process_underscore(char* payload) { switch (payload[0]) { case 'M': { + if (debugger_type != DebuggerType::LLDB) { + break; + } char* end = nullptr; req = GdbRequest(DREQ_MEM_ALLOC); req.mem_alloc().size = strtol(args, &end, 16); @@ -1006,6 +1018,9 @@ bool GdbServerConnection::process_underscore(char* payload) { return true; } case 'm': { + if (debugger_type != DebuggerType::LLDB) { + break; + } char* end = nullptr; req = GdbRequest(DREQ_MEM_FREE); req.mem_free().address = strtol(args, &end, 16); diff --git a/src/GdbServerConnection.h b/src/GdbServerConnection.h index 72e0d8c9b29..6496f33798a 100644 --- a/src/GdbServerConnection.h +++ b/src/GdbServerConnection.h @@ -797,6 +797,7 @@ class GdbServerConnection { void write_hex_bytes_packet(const uint8_t* bytes, size_t len); void write_xfer_response(const void* data, size_t size, uint64_t offset, uint64_t len); + void parse_thread_suffix_threadid(char* payload, GdbThreadId* out); /** * Consume bytes in the input buffer until start-of-packet ('$') or * the interrupt character is seen. Does not block. Return true if