From c473e52ade769945af6f99265eafd44469d6c1c9 Mon Sep 17 00:00:00 2001 From: David Spickett Date: Wed, 3 Dec 2025 13:33:20 +0000 Subject: [PATCH 1/3] [lldb] Improve logging of failure to get register information from Target XML In https://discourse.llvm.org/t/does-lldb-qemu-support-dumping-x64-control-registers-such-as-cr3/89031 a user was not seeing certain registers when connected to QEMU. Turns out their LLDB build did not have libxml2 enabled. While logging is not the first thing most users will think of, it is something an expert can ask for to confirm whether they have XML support enabled. So in this PR I've shuffled the logic GetGDBServerRegisterInfo to better report problems in the log. The key one is when lldb does not have libxml2 but the server did say it supports qxfer:features. In this case we would have used it if we could, and the debug session will likely be degraded because we are not able to. --- .../Process/gdb-remote/ProcessGDBRemote.cpp | 35 ++++++++++++++----- .../Process/gdb-remote/ProcessGDBRemote.h | 2 +- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 3c4d9a1f1ad37..6f45095c28977 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -441,8 +441,16 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) { if (!arch_to_use.IsValid()) arch_to_use = target_arch; - if (GetGDBServerRegisterInfo(arch_to_use)) + llvm::Error register_info_err = GetGDBServerRegisterInfo(arch_to_use); + if (!register_info_err) { + // We got the registers from target XML. return; + } + + Log *log = GetLog(GDBRLog::Process); + LLDB_LOG_ERROR(log, std::move(register_info_err), + "Failed to read register information from target XML: {0}"); + LLDB_LOG(log, "Now trying to use qRegisterInfo instead."); char packet[128]; std::vector registers; @@ -5137,14 +5145,19 @@ void ProcessGDBRemote::AddRemoteRegisters( // query the target of gdb-remote for extended target information returns // true on success (got register definitions), false on failure (did not). -bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) { - // Make sure LLDB has an XML parser it can use first - if (!XMLDocument::XMLEnabled()) - return false; - - // check that we have extended feature read support +llvm::Error ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) { + // If the remote does not offer XML, does not matter if we would have been + // able to parse it. if (!m_gdb_comm.GetQXferFeaturesReadSupported()) - return false; + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "The debug server does not support \"qXfer:features:read\""); + + if (!XMLDocument::XMLEnabled()) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "The debug server supports \"qXfer:features:read\", but LLDB does not " + "have XML enabled (check LLLDB_ENABLE_LIBXML2)"); // These hold register type information for the whole of target.xml. // target.xml may include further documents that @@ -5161,7 +5174,11 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) { !registers.empty()) AddRemoteRegisters(registers, arch_to_use); - return m_register_info_sp->GetNumRegisters() > 0; + return m_register_info_sp->GetNumRegisters() > 0 + ? llvm::ErrorSuccess() + : llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Debug server did not describe any registers"); } llvm::Expected ProcessGDBRemote::GetLoadedModuleList() { diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index eb33b52b57441..b7e8777c9e12e 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -416,7 +416,7 @@ class ProcessGDBRemote : public Process, void AddRemoteRegisters(std::vector ®isters, const ArchSpec &arch_to_use); // Query remote GDBServer for register information - bool GetGDBServerRegisterInfo(ArchSpec &arch); + llvm::Error GetGDBServerRegisterInfo(ArchSpec &arch); lldb::ModuleSP LoadModuleAtAddress(const FileSpec &file, lldb::addr_t link_map, From 9e25f5e2f9e2322d4e6a9685587ac532eeed04ed Mon Sep 17 00:00:00 2001 From: David Spickett Date: Thu, 4 Dec 2025 11:03:17 +0000 Subject: [PATCH 2/3] error formatting --- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 6f45095c28977..f2a085ad6648f 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -5151,12 +5151,12 @@ llvm::Error ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) { if (!m_gdb_comm.GetQXferFeaturesReadSupported()) return llvm::createStringError( llvm::inconvertibleErrorCode(), - "The debug server does not support \"qXfer:features:read\""); + "the debug server does not support \"qXfer:features:read\""); if (!XMLDocument::XMLEnabled()) return llvm::createStringError( llvm::inconvertibleErrorCode(), - "The debug server supports \"qXfer:features:read\", but LLDB does not " + "the debug server supports \"qXfer:features:read\", but LLDB does not " "have XML enabled (check LLLDB_ENABLE_LIBXML2)"); // These hold register type information for the whole of target.xml. @@ -5178,7 +5178,7 @@ llvm::Error ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) { ? llvm::ErrorSuccess() : llvm::createStringError( llvm::inconvertibleErrorCode(), - "Debug server did not describe any registers"); + "the debug server did not describe any registers"); } llvm::Expected ProcessGDBRemote::GetLoadedModuleList() { From 8311fc68ed205a614f2ad3d56e34ae546ab7be68 Mon Sep 17 00:00:00 2001 From: David Spickett Date: Thu, 4 Dec 2025 13:59:14 +0000 Subject: [PATCH 3/3] Add "parsing" --- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index f2a085ad6648f..93bd3b4a6ae03 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -5157,7 +5157,7 @@ llvm::Error ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) { return llvm::createStringError( llvm::inconvertibleErrorCode(), "the debug server supports \"qXfer:features:read\", but LLDB does not " - "have XML enabled (check LLLDB_ENABLE_LIBXML2)"); + "have XML parsing enabled (check LLLDB_ENABLE_LIBXML2)"); // These hold register type information for the whole of target.xml. // target.xml may include further documents that