From 0fc8db1c89584193386579eefa83c6f17ae23e4c Mon Sep 17 00:00:00 2001 From: Xusheng Date: Tue, 31 Mar 2026 14:54:26 +0800 Subject: [PATCH] Report errors when hardware breakpoints fail to apply with LLDB When adding a hardware execution breakpoint with the LLDB adapter before debugging, the breakpoint was silently recorded but would fail when applied. Now we warn the user upfront in the dialog, log errors when deferred hardware breakpoints fail to apply, and provide LLDB-specific guidance linking to #957. Closes #1034 Co-Authored-By: Claude Opus 4.6 (1M context) --- core/adapters/lldbadapter.cpp | 36 +++++++++++++++++++++++++++++++-- core/debuggerstate.cpp | 15 ++++++++++++-- ui/hardwarebreakpointdialog.cpp | 36 +++++++++++++++++++++++++++++++-- 3 files changed, 81 insertions(+), 6 deletions(-) diff --git a/core/adapters/lldbadapter.cpp b/core/adapters/lldbadapter.cpp index a0b4cfa9..10871e6d 100644 --- a/core/adapters/lldbadapter.cpp +++ b/core/adapters/lldbadapter.cpp @@ -2131,13 +2131,45 @@ void LldbAdapter::EventListener() { // Apply the hardware breakpoint now that process is running and stopped // Check addressing mode and call appropriate variant + bool success; if (hwbp.isRelative) { - AddHardwareBreakpoint(hwbp.location, hwbp.type, hwbp.size); + success = AddHardwareBreakpoint(hwbp.location, hwbp.type, hwbp.size); } else { - AddHardwareBreakpoint(hwbp.address, hwbp.type, hwbp.size); + success = AddHardwareBreakpoint(hwbp.address, hwbp.type, hwbp.size); + } + + if (!success) + { + uint64_t addr = hwbp.isRelative ? + (hwbp.location.offset + m_originalImageBase) : hwbp.address; + + if (hwbp.type == HardwareExecuteBreakpoint) + { + std::string arch = GetTargetArchitecture(); + if (arch == "x86_64" || arch == "i386") + { + LogError("Failed to add hardware execution breakpoint at 0x%" PRIx64 + ". Hardware execution breakpoints are not supported with the LLDB adapter" + " on x86/x64 Linux. Consider using a software breakpoint instead." + " See https://github.com/Vector35/debugger/issues/957 for details.", + addr); + } + else + { + LogError("Failed to add hardware execution breakpoint at 0x%" PRIx64 + ". The target may not support hardware breakpoints or all" + " hardware breakpoint slots may be in use.", addr); + } + } + else + { + LogError("Failed to add hardware breakpoint at 0x%" PRIx64 + ". The target may not support hardware breakpoints or all" + " hardware breakpoint slots may be in use.", addr); + } } } m_deferredHardwareBreakpoints.clear(); diff --git a/core/debuggerstate.cpp b/core/debuggerstate.cpp index c98a5192..2637a797 100644 --- a/core/debuggerstate.cpp +++ b/core/debuggerstate.cpp @@ -15,6 +15,7 @@ limitations under the License. */ #include +#include #include #include #include @@ -1126,15 +1127,25 @@ void DebuggerBreakpoints::Apply() else { // Hardware breakpoints can use either module+offset or absolute address + bool success; if (bp.isRelative) { // Use module+offset - adapter will handle resolution - m_state->GetAdapter()->AddHardwareBreakpoint(bp.location, bp.type, bp.size); + success = m_state->GetAdapter()->AddHardwareBreakpoint(bp.location, bp.type, bp.size); } else { // Use absolute address - m_state->GetAdapter()->AddHardwareBreakpoint(bp.address, bp.type, bp.size); + success = m_state->GetAdapter()->AddHardwareBreakpoint(bp.address, bp.type, bp.size); + } + + if (!success) + { + uint64_t addr = bp.isRelative ? + m_state->GetModules()->RelativeAddressToAbsolute(bp.location) : bp.address; + LogError("Failed to add hardware breakpoint at 0x%" PRIx64 + ". The target may not support this type of hardware breakpoint" + " or all hardware breakpoint slots may be in use.", addr); } } } diff --git a/ui/hardwarebreakpointdialog.cpp b/ui/hardwarebreakpointdialog.cpp index 51ce9c85..881a0a1b 100644 --- a/ui/hardwarebreakpointdialog.cpp +++ b/ui/hardwarebreakpointdialog.cpp @@ -134,6 +134,21 @@ void HardwareBreakpointDialog::addBreakpoint() if (m_controller) { + // Warn upfront if the user is trying to add a hardware execution breakpoint + // with LLDB before debugging -- it will be recorded but will fail silently later + if (type == HardwareExecuteBreakpoint + && m_controller->GetAdapterType() == "LLDB" + && !m_controller->IsConnected()) + { + QMessageBox::warning(this, "Hardware Execution Breakpoint Not Supported", + "Hardware execution breakpoints are not supported with the LLDB adapter " + "on x86/x64 Linux. The breakpoint will be saved but will fail when " + "debugging starts.\n\n" + "Consider using a software breakpoint instead.\n\n" + "See https://github.com/Vector35/debugger/issues/957 for details."); + return; + } + bool success = false; // Determine if we should use absolute or relative addressing @@ -159,8 +174,25 @@ void HardwareBreakpointDialog::addBreakpoint() } else { - QMessageBox::warning(this, "Failed to Add Breakpoint", - "Failed to add hardware breakpoint. The target may not support hardware breakpoints or all hardware breakpoint slots may be in use."); + QString message; + if (type == HardwareExecuteBreakpoint + && m_controller->GetAdapterType() == "LLDB") + { + message = "Failed to add hardware execution breakpoint.\n\n" + "This is a known issue: LLDB does not support hardware execution " + "breakpoints on x86/x64 Linux. Consider using a software breakpoint " + "instead.\n\n" + "See https://github.com/Vector35/debugger/issues/957 for details."; + } + else + { + message = "Failed to add hardware breakpoint.\n\n" + "Possible causes:\n" + " - The target does not support this type of hardware breakpoint\n" + " - All hardware breakpoint slots are in use\n" + " - The address is not valid for a hardware breakpoint"; + } + QMessageBox::warning(this, "Failed to Add Breakpoint", message); } } }