[Lldb-commits] [lldb] 185ef69 - [lldb] Don't call CopyForBreakpoint from a Breakpoint's constructor
Tatyana Krasnukha via lldb-commits
lldb-commits at lists.llvm.org
Tue Feb 18 02:49:32 PST 2020
Author: Tatyana Krasnukha
Date: 2020-02-18T13:49:07+03:00
New Revision: 185ef697ef5c60d7a5c801925e6abdad52226c2b
URL: https://github.com/llvm/llvm-project/commit/185ef697ef5c60d7a5c801925e6abdad52226c2b
DIFF: https://github.com/llvm/llvm-project/commit/185ef697ef5c60d7a5c801925e6abdad52226c2b.diff
LOG: [lldb] Don't call CopyForBreakpoint from a Breakpoint's constructor
Some implementations (BreakpointResolverScripted) try calling the breakpoint's shared_from_this(),
that makes LLDB crash.
Added:
Modified:
lldb/include/lldb/Breakpoint/Breakpoint.h
lldb/source/Breakpoint/Breakpoint.cpp
lldb/source/Target/Target.cpp
lldb/test/API/functionalities/breakpoint/scripted_bkpt/TestScriptedResolver.py
Removed:
################################################################################
diff --git a/lldb/include/lldb/Breakpoint/Breakpoint.h b/lldb/include/lldb/Breakpoint/Breakpoint.h
index 553b911da0f7..c48a0ad73d4e 100644
--- a/lldb/include/lldb/Breakpoint/Breakpoint.h
+++ b/lldb/include/lldb/Breakpoint/Breakpoint.h
@@ -568,6 +568,11 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
return GetPermissions().GetAllowDelete();
}
+ // This one should only be used by Target to copy breakpoints from target to
+ // target - primarily from the dummy target to prime new targets.
+ static lldb::BreakpointSP CopyFromBreakpoint(Target& new_target,
+ const Breakpoint &bp_to_copy_from);
+
protected:
friend class Target;
// Protected Methods
@@ -625,9 +630,8 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
}
private:
- // This one should only be used by Target to copy breakpoints from target to
- // target - primarily from the dummy target to prime new targets.
- Breakpoint(Target &new_target, Breakpoint &bp_to_copy_from);
+ // To call from CopyFromBreakpoint.
+ Breakpoint(Target &new_target, const Breakpoint &bp_to_copy_from);
// For Breakpoint only
bool m_being_created;
diff --git a/lldb/source/Breakpoint/Breakpoint.cpp b/lldb/source/Breakpoint/Breakpoint.cpp
index 78aef01d35aa..39c6828d3f09 100644
--- a/lldb/source/Breakpoint/Breakpoint.cpp
+++ b/lldb/source/Breakpoint/Breakpoint.cpp
@@ -55,21 +55,26 @@ Breakpoint::Breakpoint(Target &target, SearchFilterSP &filter_sp,
m_being_created = false;
}
-Breakpoint::Breakpoint(Target &new_target, Breakpoint &source_bp)
+Breakpoint::Breakpoint(Target &new_target, const Breakpoint &source_bp)
: m_being_created(true), m_hardware(source_bp.m_hardware),
m_target(new_target), m_name_list(source_bp.m_name_list),
m_options_up(new BreakpointOptions(*source_bp.m_options_up)),
m_locations(*this),
m_resolve_indirect_symbols(source_bp.m_resolve_indirect_symbols),
- m_hit_count(0) {
- // Now go through and copy the filter & resolver:
- m_resolver_sp = source_bp.m_resolver_sp->CopyForBreakpoint(*this);
- m_filter_sp = source_bp.m_filter_sp->CopyForBreakpoint(*this);
-}
+ m_hit_count(0) {}
// Destructor
Breakpoint::~Breakpoint() = default;
+BreakpointSP Breakpoint::CopyFromBreakpoint(Target& new_target,
+ const Breakpoint& bp_to_copy_from) {
+ BreakpointSP bp(new Breakpoint(new_target, bp_to_copy_from));
+ // Now go through and copy the filter & resolver:
+ bp->m_resolver_sp = bp_to_copy_from.m_resolver_sp->CopyForBreakpoint(*bp);
+ bp->m_filter_sp = bp_to_copy_from.m_filter_sp->CopyForBreakpoint(*bp);
+ return bp;
+}
+
// Serialization
StructuredData::ObjectSP Breakpoint::SerializeToStructuredData() {
// Serialize the resolver:
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 9e41e90b6d7d..49cb52bb0498 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -127,12 +127,12 @@ void Target::PrimeFromDummyTarget(Target *target) {
m_stop_hooks = target->m_stop_hooks;
- for (BreakpointSP breakpoint_sp : target->m_breakpoint_list.Breakpoints()) {
+ for (const auto &breakpoint_sp : target->m_breakpoint_list.Breakpoints()) {
if (breakpoint_sp->IsInternal())
continue;
- BreakpointSP new_bp(new Breakpoint(*this, *breakpoint_sp.get()));
- AddBreakpoint(new_bp, false);
+ BreakpointSP new_bp(Breakpoint::CopyFromBreakpoint(*this, *breakpoint_sp));
+ AddBreakpoint(std::move(new_bp), false);
}
for (auto bp_name_entry : target->m_breakpoint_names) {
diff --git a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/TestScriptedResolver.py b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/TestScriptedResolver.py
index 9f0ba1116867..b0b04119a4f0 100644
--- a/lldb/test/API/functionalities/breakpoint/scripted_bkpt/TestScriptedResolver.py
+++ b/lldb/test/API/functionalities/breakpoint/scripted_bkpt/TestScriptedResolver.py
@@ -40,8 +40,21 @@ def test_bad_command_lines(self):
self.build()
self.do_test_bad_options()
+ @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24528")
+ def test_copy_from_dummy_target(self):
+ """Make sure we don't crash during scripted breakpoint copy from dummy target"""
+ self.build()
+ self.do_test_copy_from_dummy_target()
+
def make_target_and_import(self):
- target = lldbutil.run_to_breakpoint_make_target(self)
+ target = self.make_target()
+ self.import_resolver_script()
+ return target
+
+ def make_target(self):
+ return lldbutil.run_to_breakpoint_make_target(self)
+
+ def import_resolver_script(self):
interp = self.dbg.GetCommandInterpreter()
error = lldb.SBError()
@@ -52,7 +65,6 @@ def make_target_and_import(self):
result = lldb.SBCommandReturnObject()
interp.HandleCommand(command, result)
self.assertTrue(result.Succeeded(), "com scr imp failed: %s"%(result.GetError()))
- return target
def make_extra_args(self):
json_string = '{"symbol":"break_on_me", "test1": "value1"}'
@@ -222,3 +234,23 @@ def do_test_bad_options(self):
substrs=['Value: "a_value" missing matching key'])
self.expect("break set -P resolver.Resolver -k a_key -k a_key -v another_value", error = True, msg="Missing value among args",
substrs=['Key: "a_key" missing value'])
+
+ def do_test_copy_from_dummy_target(self):
+ # Import breakpoint scripted resolver.
+ self.import_resolver_script()
+
+ # Create a scripted breakpoint.
+ self.runCmd("breakpoint set -P resolver.Resolver -k symbol -v break_on_me",
+ BREAKPOINT_CREATED)
+
+ # This is the function to remove breakpoints from the dummy target
+ # to get a clean state for the next test case.
+ def cleanup():
+ self.runCmd('breakpoint delete -D -f', check=False)
+ self.runCmd('breakpoint list', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ # Check that target creating doesn't crash.
+ target = self.make_target()
More information about the lldb-commits
mailing list