[Lldb-commits] [lldb] 3a025e4 - [lldb] Copy valid breakpoint overrides from the dummy target (#235834)
via lldb-commits
lldb-commits at lists.llvm.org
Thu Oct 29 18:06:41 PDT 2026
Author: Alexandre Perez
Date: 2026-10-29T18:06:35-07:00
New Revision: 3a025e4b02ea483a4a1b60b1248c3665b4dfda60
URL: https://github.com/llvm/llvm-project/commit/3a025e4b02ea483a4a1b60b1248c3665b4dfda60
DIFF: https://github.com/llvm/llvm-project/commit/3a025e4b02ea483a4a1b60b1248c3665b4dfda60.diff
LOG: [lldb] Copy valid breakpoint overrides from the dummy target (#235834)
`Target::PrimeFromDummyTarget` copied a breakpoint override into a new target only when `Validate` failed, because an `llvm::Error` converts to true on failure. Overrides registered on the dummy target therefore never reached later targets. Copy the overrides that validate, and log the error of those that don't.
Rename `Validate` to `HasErrors`, still returning an `llvm::Error`, so call sites read the right way round. It now also checks that the override's class exists, so adding an override with a missing class fails with a useful error instead of failing on every matching breakpoint.
Test both: an override on the dummy target applies to targets created later, and `test_bad_values` now covers a missing class.
Added:
Modified:
lldb/include/lldb/Breakpoint/ScriptedBreakpointOverrideResolver.h
lldb/include/lldb/Target/Target.h
lldb/source/Breakpoint/ScriptedBreakpointOverrideResolver.cpp
lldb/source/Target/Target.cpp
lldb/test/API/functionalities/breakpoint/scripted_bkpt/overrides_resolver/TestOverridesResolver.py
Removed:
################################################################################
diff --git a/lldb/include/lldb/Breakpoint/ScriptedBreakpointOverrideResolver.h b/lldb/include/lldb/Breakpoint/ScriptedBreakpointOverrideResolver.h
index f787421b41303f..18149e188a6346 100644
--- a/lldb/include/lldb/Breakpoint/ScriptedBreakpointOverrideResolver.h
+++ b/lldb/include/lldb/Breakpoint/ScriptedBreakpointOverrideResolver.h
@@ -37,7 +37,7 @@ class ScriptedBreakpointResolverOverride
CheckForOverride(Target &target,
lldb::BreakpointResolverSP initial_sp) override;
- llvm::Error Validate() override;
+ llvm::Error HasErrors() override;
private:
StructuredDataImpl m_args_data;
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index 97d2a58d68e629..781683caf2db63 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -1063,8 +1063,9 @@ class Target : public std::enable_shared_from_this<Target>,
virtual ~BreakpointResolverOverride() {}
virtual lldb::BreakpointResolverSP
CheckForOverride(Target &target, lldb::BreakpointResolverSP initial_sp) = 0;
- // Return whether constructing this resolver was successful.
- virtual llvm::Error Validate() = 0;
+ // Returns an error describing why this override can't be used, for
+ // example because its script class doesn't exist.
+ virtual llvm::Error HasErrors() = 0;
const std::string &GetDescription() { return m_desc; }
uint64_t GetTypeMask() { return m_type_mask; }
std::string DescribeTypeMask();
diff --git a/lldb/source/Breakpoint/ScriptedBreakpointOverrideResolver.cpp b/lldb/source/Breakpoint/ScriptedBreakpointOverrideResolver.cpp
index 6adab023307708..f3782c84c68aef 100644
--- a/lldb/source/Breakpoint/ScriptedBreakpointOverrideResolver.cpp
+++ b/lldb/source/Breakpoint/ScriptedBreakpointOverrideResolver.cpp
@@ -9,6 +9,9 @@
#include "lldb/Breakpoint/ScriptedBreakpointOverrideResolver.h"
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointResolverScripted.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Interpreter/ScriptInterpreter.h"
+#include "llvm/Support/ErrorExtras.h"
namespace lldb_private {
lldb::BreakpointResolverSP ScriptedBreakpointResolverOverride::CheckForOverride(
@@ -20,9 +23,12 @@ lldb::BreakpointResolverSP ScriptedBreakpointResolverOverride::CheckForOverride(
return {};
}
-llvm::Error ScriptedBreakpointResolverOverride::Validate() {
- // FIXME: we should make sure the module and class exist, though that will
- // to happen in a scripting language specific function.
+llvm::Error ScriptedBreakpointResolverOverride::HasErrors() {
+ ScriptInterpreter *interpreter =
+ m_target.GetDebugger().GetScriptInterpreter();
+ if (!interpreter || !interpreter->CheckObjectExists(m_class_name.c_str()))
+ return llvm::createStringErrorV(
+ "class for breakpoint override: \"{0}\" does not exist", m_class_name);
return llvm::Error::success();
}
} // namespace lldb_private
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index db53649a145c00..262b559623edb5 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -248,7 +248,11 @@ void Target::PrimeFromDummyTarget(Target &target) {
for (auto const &elem : target.m_breakpoint_overrides) {
BreakpointResolverOverrideUP new_override_up =
elem.second->CopyIntoNewTarget(*this);
- if (new_override_up->Validate())
+ if (llvm::Error error = new_override_up->HasErrors())
+ LLDB_LOG_ERROR(GetLog(LLDBLog::Breakpoints), std::move(error),
+ "Can't copy breakpoint override from the dummy target: "
+ "{0}");
+ else
AddBreakpointResolverOverride(std::move(new_override_up));
}
@@ -991,7 +995,7 @@ llvm::Expected<lldb::user_id_t> Target::AddBreakpointResolverOverride(
new ScriptedBreakpointResolverOverride(*this, std::string(description),
type_mask, std::string(class_name),
impl));
- llvm::Error error = new_override_up->Validate();
+ llvm::Error error = new_override_up->HasErrors();
if (error)
return error;
diff --git a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/overrides_resolver/TestOverridesResolver.py b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/overrides_resolver/TestOverridesResolver.py
index 83c23d62a2bfee..906e80fdade26b 100644
--- a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/overrides_resolver/TestOverridesResolver.py
+++ b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/overrides_resolver/TestOverridesResolver.py
@@ -28,6 +28,34 @@ def test_bad_values(self):
self.build()
self.do_test_bad_values()
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528")
+ def test_overrides_copied_from_dummy_target(self):
+ """An override on the dummy target applies to targets created later."""
+ self.build()
+ self.import_resolver_script()
+ extra_args = lldb.SBStructuredData()
+ extra_args.SetFromJSON('{"symbol": "stop_here_instead"}')
+ error = lldb.SBError()
+ self.dbg.GetDummyTarget().AddBreakpointOverride(
+ "bkpt_resolver.OverrideExample",
+ "dummy target override",
+ lldb.eResolverFileAndLine,
+ extra_args,
+ error,
+ )
+ self.assertSuccess(error)
+
+ target = self.createTestTarget()
+ self.expect("breakpoint override list", substrs=["dummy target override"])
+ bkpt = target.BreakpointCreateByLocation(
+ "main.c", line_number("main.c", "I am in the stop symbol")
+ )
+ self.assertEqual(bkpt.GetNumLocations(), 1)
+ self.assertEqual(
+ bkpt.GetLocationAtIndex(0).GetAddress().GetFunction().GetName(),
+ "stop_here_instead",
+ )
+
def make_target_and_import(self):
self.target = lldbutil.run_to_breakpoint_make_target(self)
self.import_resolver_script()
@@ -103,6 +131,8 @@ def add_override_cmd(
override_id = int(result.GetOutput())
else:
self.assertFalse(result.Succeeded(), "We expected this to fail")
+ if error_string:
+ self.assertIn(error_string, result.GetError())
return 0
# Check the override listing, make sure our new entry is present:
@@ -280,18 +310,30 @@ def do_test_bad_values(self):
expect_error=True,
error_string="empty class name",
)
- # FIXME: We aren't currently returning a correct
- # error when the class name doesn't exist.
# And with a class name that doesn't exist:
- # trivial_id = self.add_override_python(
- # trivial_help,
- # "NoModuleOfThisName.NoClassOfThisName",
- # lldb.eResolverName,
- # "test_key",
- # "test_value",
- # expect_error=True,
- # error_string=""
- # )
+ missing_class = "NoModuleOfThisName.NoClassOfThisName"
+ missing_class_error = (
+ f'class for breakpoint override: "{missing_class}" does not exist'
+ )
+ trivial_id = self.add_override_python(
+ trivial_help,
+ missing_class,
+ lldb.eResolverName,
+ "test_key",
+ "test_value",
+ expect_error=True,
+ error_string=missing_class_error,
+ )
+ trivial_id = self.add_override_cmd(
+ trivial_help,
+ missing_class,
+ "-m name",
+ "",
+ "test_key",
+ "test_value",
+ expect_error=True,
+ error_string=missing_class_error,
+ )
trivial_id = self.add_override_cmd(
trivial_help,
More information about the lldb-commits
mailing list