From 92d1960e3b63c4c9ca7e7af3463b39c46864c792 Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Tue, 20 Sep 2016 22:54:49 +0000 Subject: [PATCH] Add some more tests for breakpoint serialization. Serialize breakpoint names & the hardware_requested attributes. Also added a few missing affordances to SBBreakpoint whose absence writing the tests pointed out. llvm-svn: 282036 --- lldb/include/lldb/API/SBBreakpoint.h | 6 +- lldb/include/lldb/API/SBStringList.h | 3 + lldb/include/lldb/API/SBTarget.h | 4 + lldb/include/lldb/Breakpoint/Breakpoint.h | 11 ++ lldb/include/lldb/Breakpoint/BreakpointOptions.h | 21 ++- .../serialize/TestBreakpointSerialization.py | 144 ++++++++++++++------- lldb/scripts/interface/SBBreakpoint.i | 4 + lldb/scripts/interface/SBTarget.i | 4 + lldb/source/API/SBBreakpoint.cpp | 25 ++++ lldb/source/API/SBStringList.cpp | 6 + lldb/source/API/SBTarget.cpp | 18 ++- lldb/source/Breakpoint/Breakpoint.cpp | 38 +++++- lldb/source/Breakpoint/BreakpointOptions.cpp | 46 +++++-- .../Commands/CommandObjectBreakpointCommand.cpp | 4 +- 14 files changed, 270 insertions(+), 64 deletions(-) diff --git a/lldb/include/lldb/API/SBBreakpoint.h b/lldb/include/lldb/API/SBBreakpoint.h index a93050a..7924229 100644 --- a/lldb/include/lldb/API/SBBreakpoint.h +++ b/lldb/include/lldb/API/SBBreakpoint.h @@ -88,6 +88,10 @@ public: void SetScriptCallbackFunction(const char *callback_function_name); + void SetCommandLineCommands(SBStringList &commands); + + bool GetCommandLineCommands(SBStringList &commands); + SBError SetScriptCallbackBody(const char *script_body_text); bool AddName(const char *new_name); @@ -154,7 +158,7 @@ public: SBBreakpoint GetBreakpointAtIndex(size_t idx); - SBBreakpoint FindBreakpointByID(lldb::break_id_t); + SBBreakpoint FindBreakpointByID(lldb::break_id_t); void Append(const SBBreakpoint &sb_file); diff --git a/lldb/include/lldb/API/SBStringList.h b/lldb/include/lldb/API/SBStringList.h index ac62fce2..66b5172 100644 --- a/lldb/include/lldb/API/SBStringList.h +++ b/lldb/include/lldb/API/SBStringList.h @@ -43,9 +43,12 @@ public: protected: friend class SBCommandInterpreter; friend class SBDebugger; + friend class SBBreakpoint; SBStringList(const lldb_private::StringList *lldb_strings); + void AppendList(const lldb_private::StringList &strings); + const lldb_private::StringList *operator->() const; const lldb_private::StringList &operator*() const; diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h index c7d99b1..ac22586 100644 --- a/lldb/include/lldb/API/SBTarget.h +++ b/lldb/include/lldb/API/SBTarget.h @@ -564,6 +564,10 @@ public: BreakpointCreateByLocation(const lldb::SBFileSpec &file_spec, uint32_t line, lldb::addr_t offset); + lldb::SBBreakpoint + BreakpointCreateByLocation(const lldb::SBFileSpec &file_spec, uint32_t line, + lldb::addr_t offset, SBFileSpecList &module_list); + lldb::SBBreakpoint BreakpointCreateByName(const char *symbol_name, const char *module_name = nullptr); diff --git a/lldb/include/lldb/Breakpoint/Breakpoint.h b/lldb/include/lldb/Breakpoint/Breakpoint.h index e002f71..03a92ca 100644 --- a/lldb/include/lldb/Breakpoint/Breakpoint.h +++ b/lldb/include/lldb/Breakpoint/Breakpoint.h @@ -107,6 +107,17 @@ public: //------------------------------------------------------------------ typedef enum { Exact, Regexp, Glob } MatchType; +private: + enum class OptionNames : uint32_t { Names = 0, Hardware, LastOptionName }; + + static const char + *g_option_names[static_cast(OptionNames::LastOptionName)]; + + static const char *GetKey(OptionNames enum_value) { + return g_option_names[static_cast(enum_value)]; + } + +public: class BreakpointEventData : public EventData { public: BreakpointEventData(lldb::BreakpointEventType sub_type, diff --git a/lldb/include/lldb/Breakpoint/BreakpointOptions.h b/lldb/include/lldb/Breakpoint/BreakpointOptions.h index c7763bd..1b72ba0 100644 --- a/lldb/include/lldb/Breakpoint/BreakpointOptions.h +++ b/lldb/include/lldb/Breakpoint/BreakpointOptions.h @@ -36,6 +36,9 @@ public: struct CommandData { CommandData() : user_source(), script_source(), stop_on_error(true) {} + CommandData(const StringList &user_source) + : user_source(user_source), script_source(), stop_on_error(true) {} + ~CommandData() = default; static const char *GetSerializationKey() { return "BKPTCMDData"; } @@ -180,6 +183,18 @@ public: bool synchronous = false); //------------------------------------------------------------------ + /// Returns the command line commands for the callback on this breakpoint. + /// + /// @param[out] command_list + /// The commands will be appended to this list. + /// + /// @return + /// \btrue if the command callback is a command-line callback, + /// \bfalse otherwise. + //------------------------------------------------------------------ + bool GetCommandLineCallbacks(StringList &command_list); + + //------------------------------------------------------------------ /// Remove the callback from this option set. //------------------------------------------------------------------ void ClearCallback(); @@ -335,10 +350,10 @@ public: //------------------------------------------------------------------ /// Set a callback based on BreakpointOptions::CommandData. /// @param[in] cmd_data - /// A new'ed CommandData object. The breakpoint will take ownership - /// of this object. + /// A UP holding the new'ed CommandData object. + /// The breakpoint will take ownership of pointer held by this object. //------------------------------------------------------------------ - void SetCommandDataCallback(std::unique_ptr cmd_data); + void SetCommandDataCallback(std::unique_ptr &cmd_data); protected: //------------------------------------------------------------------ diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py index 3f8a393..e609d8e 100644 --- a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py +++ b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py @@ -1,5 +1,5 @@ """ -Test breakpoint ignore count features. +Test breakpoint serialization. """ from __future__ import print_function @@ -25,34 +25,28 @@ class BreakpointSerialization(TestBase): self.setup_targets_and_cleanup() self.do_check_resolvers() - def not_test_filters(self): + def test_filters(self): """Use Python APIs to test that we serialize search filters correctly.""" self.build() self.setup_targets_and_cleanup() - self.check_filters() + self.do_check_filters() - def not_test_options(self): + def test_options(self): """Use Python APIs to test that we serialize breakpoint options correctly.""" self.build() self.setup_targets_and_cleanup() - self.check_filters() - - def not_test_complex(self): - """Use Python APIs to test that we serialize complex breakpoints correctly.""" - self.build() - self.setup_targets_and_cleanup() - self.check_filters() + self.do_check_options() def setup_targets_and_cleanup(self): def cleanup (): - #self.RemoveTempFile(self.bkpts_file_path) + self.RemoveTempFile(self.bkpts_file_path) if self.orig_target.IsValid(): self.dbg.DeleteTarget(self.orig_target) self.dbg.DeleteTarget(self.copy_target) self.addTearDownHook(cleanup) - #self.RemoveTempFile(self.bkpts_file_path) + self.RemoveTempFile(self.bkpts_file_path) exe = os.path.join(os.getcwd(), "a.out") @@ -70,23 +64,10 @@ class BreakpointSerialization(TestBase): self.bkpts_file_path = os.path.join(os.getcwd(), "breakpoints.json") self.bkpts_file_spec = lldb.SBFileSpec(self.bkpts_file_path) - def do_check_resolvers(self): - """Use Python APIs to check serialization of breakpoint resolvers""" - - empty_module_list = lldb.SBFileSpecList() - empty_cu_list = lldb.SBFileSpecList() - blubby_file_spec = lldb.SBFileSpec(os.path.join(os.getcwd(), "blubby.c")) - - # It isn't actually important for these purposes that these breakpoint - # actually have locations. - source_bps = lldb.SBBreakpointList(self.orig_target) - source_bps.Append(self.orig_target.BreakpointCreateByLocation("blubby.c", 666)) - source_bps.Append(self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeAuto, empty_module_list, empty_cu_list)) - source_bps.Append(self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeFull, empty_module_list,empty_cu_list)) - source_bps.Append(self.orig_target.BreakpointCreateBySourceRegex("dont really care", blubby_file_spec)) + def check_equivalence(self, source_bps): error = lldb.SBError() - error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec) + error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec, source_bps) self.assertTrue(error.Success(), "Failed writing breakpoints to file: %s."%(error.GetCString())) copy_bps = lldb.SBBreakpointList(self.copy_target) @@ -116,32 +97,105 @@ class BreakpointSerialization(TestBase): copy_text = copy_desc.GetData() # These two should be identical. - print ("Source test for %d is %s."%(i, source_text)) + # print ("Source text for %d is %s."%(i, source_text)) self.assertTrue (source_text == copy_text, "Source and dest breakpoints are not identical: \nsource: %s\ndest: %s"%(source_text, copy_text)) - def check_filters(self): + def do_check_resolvers(self): + """Use Python APIs to check serialization of breakpoint resolvers""" + + empty_module_list = lldb.SBFileSpecList() + empty_cu_list = lldb.SBFileSpecList() + blubby_file_spec = lldb.SBFileSpec(os.path.join(os.getcwd(), "blubby.c")) + + # It isn't actually important for these purposes that these breakpoint + # actually have locations. + source_bps = lldb.SBBreakpointList(self.orig_target) + source_bps.Append(self.orig_target.BreakpointCreateByLocation("blubby.c", 666)) + # Make sure we do one breakpoint right: + self.check_equivalence(source_bps) + source_bps.Clear() + + source_bps.Append(self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeAuto, empty_module_list, empty_cu_list)) + source_bps.Append(self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeFull, empty_module_list,empty_cu_list)) + source_bps.Append(self.orig_target.BreakpointCreateBySourceRegex("dont really care", blubby_file_spec)) + + # And some number greater than one: + self.check_equivalence(source_bps) + + def do_check_filters(self): """Use Python APIs to check serialization of breakpoint filters.""" - exe = os.path.join(os.getcwd(), "a.out") + module_list = lldb.SBFileSpecList() + module_list.Append(lldb.SBFileSpec("SomeBinary")) + module_list.Append(lldb.SBFileSpec("SomeOtherBinary")) + + cu_list = lldb.SBFileSpecList() + cu_list.Append(lldb.SBFileSpec("SomeCU.c")) + cu_list.Append(lldb.SBFileSpec("AnotherCU.c")) + cu_list.Append(lldb.SBFileSpec("ThirdCU.c")) - # Create a target by the debugger. - target = self.dbg.CreateTarget(exe) - self.assertTrue(target, VALID_TARGET) + blubby_file_spec = lldb.SBFileSpec(os.path.join(os.getcwd(), "blubby.c")) - def check_options(self): + # It isn't actually important for these purposes that these breakpoint + # actually have locations. + source_bps = lldb.SBBreakpointList(self.orig_target) + bkpt = self.orig_target.BreakpointCreateByLocation(blubby_file_spec, 666, 0, module_list) + source_bps.Append(bkpt) + + # Make sure we do one right: + self.check_equivalence(source_bps) + source_bps.Clear() + + bkpt = self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeAuto, module_list, cu_list) + source_bps.Append(bkpt) + bkpt = self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeFull, module_list, cu_list) + source_bps.Append(bkpt) + bkpt = self.orig_target.BreakpointCreateBySourceRegex("dont really care", blubby_file_spec) + source_bps.Append(bkpt) + + # And some number greater than one: + self.check_equivalence(source_bps) + + def do_check_options(self): """Use Python APIs to check serialization of breakpoint options.""" - exe = os.path.join(os.getcwd(), "a.out") - # Create a target by the debugger. - target = self.dbg.CreateTarget(exe) - self.assertTrue(target, VALID_TARGET) + empty_module_list = lldb.SBFileSpecList() + empty_cu_list = lldb.SBFileSpecList() + blubby_file_spec = lldb.SBFileSpec(os.path.join(os.getcwd(), "blubby.c")) - def check_resolvers(self): - """Use Python APIs to check serialization of breakpoint resolvers.""" - exe = os.path.join(os.getcwd(), "a.out") + # It isn't actually important for these purposes that these breakpoint + # actually have locations. + source_bps = lldb.SBBreakpointList(self.orig_target) + + bkpt = self.orig_target.BreakpointCreateByLocation("blubby.c", 666) + bkpt.SetEnabled(False) + bkpt.SetOneShot(True) + source_bps.Append(bkpt) + + # Make sure we get one right: + self.check_equivalence(source_bps) + source_bps.Clear() + + bkpt = self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeAuto, empty_module_list, empty_cu_list) + bkpt.SetIgnoreCount(10) + source_bps.Append(bkpt) + + bkpt = self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeFull, empty_module_list,empty_cu_list) + bkpt.SetCondition("something != something_else") + bkpt.AddName("FirstName") + bkpt.AddName("SecondName") + + source_bps.Append(bkpt) + + bkpt = self.orig_target.BreakpointCreateBySourceRegex("dont really care", blubby_file_spec) + cmd_list = lldb.SBStringList() + cmd_list.AppendString("frame var") + cmd_list.AppendString("thread backtrace") + + bkpt.SetCommandLineCommands(cmd_list) + source_bps.Append(bkpt) + + self.check_equivalence(source_bps) - # Create a target by the debugger. - target = self.dbg.CreateTarget(exe) - self.assertTrue(target, VALID_TARGET) diff --git a/lldb/scripts/interface/SBBreakpoint.i b/lldb/scripts/interface/SBBreakpoint.i index 9098c6e..22c4c21 100644 --- a/lldb/scripts/interface/SBBreakpoint.i +++ b/lldb/scripts/interface/SBBreakpoint.i @@ -200,6 +200,10 @@ public: SBError SetScriptCallbackBody (const char *script_body_text); + void SetCommandLineCommands(SBStringList &commands); + + bool GetCommandLineCommands(SBStringList &commands); + bool AddName (const char *new_name); diff --git a/lldb/scripts/interface/SBTarget.i b/lldb/scripts/interface/SBTarget.i index f907dcc..f490be5 100644 --- a/lldb/scripts/interface/SBTarget.i +++ b/lldb/scripts/interface/SBTarget.i @@ -589,6 +589,10 @@ public: BreakpointCreateByLocation (const lldb::SBFileSpec &file_spec, uint32_t line, lldb::addr_t offset); lldb::SBBreakpoint + BreakpointCreateByLocation (const lldb::SBFileSpec &file_spec, uint32_t line, + lldb::addr_t offset, SBFileSpecList &module_list); + + lldb::SBBreakpoint BreakpointCreateByName (const char *symbol_name, const char *module_name = NULL); lldb::SBBreakpoint diff --git a/lldb/source/API/SBBreakpoint.cpp b/lldb/source/API/SBBreakpoint.cpp index 7276713..7194101 100644 --- a/lldb/source/API/SBBreakpoint.cpp +++ b/lldb/source/API/SBBreakpoint.cpp @@ -448,6 +448,31 @@ size_t SBBreakpoint::GetNumLocations() const { return num_locs; } +void SBBreakpoint::SetCommandLineCommands(SBStringList &commands) { + if (!m_opaque_sp) + return; + if (commands.GetSize() == 0) + return; + + std::lock_guard guard( + m_opaque_sp->GetTarget().GetAPIMutex()); + std::unique_ptr cmd_data_up( + new BreakpointOptions::CommandData(*commands)); + + m_opaque_sp->GetOptions()->SetCommandDataCallback(cmd_data_up); +} + +bool SBBreakpoint::GetCommandLineCommands(SBStringList &commands) { + if (!m_opaque_sp) + return false; + StringList command_list; + bool has_commands = + m_opaque_sp->GetOptions()->GetCommandLineCallbacks(command_list); + if (has_commands) + commands.AppendList(command_list); + return has_commands; +} + bool SBBreakpoint::GetDescription(SBStream &s) { return GetDescription(s, true); } diff --git a/lldb/source/API/SBStringList.cpp b/lldb/source/API/SBStringList.cpp index 34465f7..075ee0d 100644 --- a/lldb/source/API/SBStringList.cpp +++ b/lldb/source/API/SBStringList.cpp @@ -75,6 +75,12 @@ void SBStringList::AppendList(const SBStringList &strings) { } } +void SBStringList::AppendList(const StringList &strings) { + if (!IsValid()) + m_opaque_ap.reset(new lldb_private::StringList()); + m_opaque_ap->AppendList(strings); +} + uint32_t SBStringList::GetSize() const { if (IsValid()) { return m_opaque_ap->GetSize(); diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp index 66d375a..7cf9215 100644 --- a/lldb/source/API/SBTarget.cpp +++ b/lldb/source/API/SBTarget.cpp @@ -661,6 +661,14 @@ SBTarget::BreakpointCreateByLocation(const SBFileSpec &sb_file_spec, SBBreakpoint SBTarget::BreakpointCreateByLocation(const SBFileSpec &sb_file_spec, uint32_t line, lldb::addr_t offset) { + SBFileSpecList empty_list; + return BreakpointCreateByLocation(sb_file_spec, line, offset, empty_list); +} + +SBBreakpoint +SBTarget::BreakpointCreateByLocation(const SBFileSpec &sb_file_spec, + uint32_t line, lldb::addr_t offset, + SBFileSpecList &sb_module_list) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); SBBreakpoint sb_bp; @@ -673,9 +681,13 @@ SBTarget::BreakpointCreateByLocation(const SBFileSpec &sb_file_spec, const bool internal = false; const bool hardware = false; const LazyBool move_to_nearest_code = eLazyBoolCalculate; - *sb_bp = target_sp->CreateBreakpoint(NULL, *sb_file_spec, line, offset, - check_inlines, skip_prologue, internal, - hardware, move_to_nearest_code); + const FileSpecList *module_list = nullptr; + if (sb_module_list.GetSize() > 0) { + module_list = sb_module_list.get(); + } + *sb_bp = target_sp->CreateBreakpoint( + module_list, *sb_file_spec, line, offset, check_inlines, skip_prologue, + internal, hardware, move_to_nearest_code); } if (log) { diff --git a/lldb/source/Breakpoint/Breakpoint.cpp b/lldb/source/Breakpoint/Breakpoint.cpp index 567ceaa..a9666f4 100644 --- a/lldb/source/Breakpoint/Breakpoint.cpp +++ b/lldb/source/Breakpoint/Breakpoint.cpp @@ -41,6 +41,9 @@ const ConstString &Breakpoint::GetEventIdentifier() { return g_identifier; } +const char *Breakpoint::g_option_names[static_cast( + Breakpoint::OptionNames::LastOptionName)]{"Names", "Hardware"}; + //---------------------------------------------------------------------- // Breakpoint constructor //---------------------------------------------------------------------- @@ -81,6 +84,19 @@ StructuredData::ObjectSP Breakpoint::SerializeToStructuredData() { StructuredData::DictionarySP breakpoint_contents_sp( new StructuredData::Dictionary()); + if (!m_name_list.empty()) { + StructuredData::ArraySP names_array_sp(new StructuredData::Array()); + for (auto name : m_name_list) { + names_array_sp->AddItem( + StructuredData::StringSP(new StructuredData::String(name))); + } + breakpoint_contents_sp->AddItem(Breakpoint::GetKey(OptionNames::Names), + names_array_sp); + } + + breakpoint_contents_sp->AddBooleanItem( + Breakpoint::GetKey(OptionNames::Hardware), m_hardware); + StructuredData::ObjectSP resolver_dict_sp( m_resolver_sp->SerializeToStructuredData()); if (!resolver_dict_sp) @@ -172,11 +188,31 @@ lldb::BreakpointSP Breakpoint::CreateFromStructuredData( return result_sp; } } + + bool hardware = false; + success = breakpoint_dict->GetValueForKeyAsBoolean( + Breakpoint::GetKey(OptionNames::Hardware), hardware); + result_sp = - target.CreateBreakpoint(filter_sp, resolver_sp, false, false, true); + target.CreateBreakpoint(filter_sp, resolver_sp, false, hardware, true); + if (result_sp && options_up) { result_sp->m_options_up = std::move(options_up); } + + StructuredData::Array *names_array; + success = breakpoint_dict->GetValueForKeyAsArray( + Breakpoint::GetKey(OptionNames::Names), names_array); + if (success && names_array) { + size_t num_names = names_array->GetSize(); + for (size_t i = 0; i < num_names; i++) { + std::string name; + Error error; + success = names_array->GetItemAtIndexAsString(i, name); + result_sp->AddName(name.c_str(), error); + } + } + return result_sp; } diff --git a/lldb/source/Breakpoint/BreakpointOptions.cpp b/lldb/source/Breakpoint/BreakpointOptions.cpp index d55a344..3095f77 100644 --- a/lldb/source/Breakpoint/BreakpointOptions.cpp +++ b/lldb/source/Breakpoint/BreakpointOptions.cpp @@ -66,26 +66,39 @@ std::unique_ptr BreakpointOptions::CommandData::CreateFromStructuredData( const StructuredData::Dictionary &options_dict, Error &error) { std::string script_source; - CommandData *data = new CommandData(); + std::unique_ptr data_up(new CommandData()); + bool found_something = false; + bool success = options_dict.GetValueForKeyAsBoolean( - GetKey(OptionNames::StopOnError), data->stop_on_error); + GetKey(OptionNames::StopOnError), data_up->stop_on_error); + + if (success) + found_something = true; success = options_dict.GetValueForKeyAsString( - GetKey(OptionNames::ScriptSource), data->script_source); + GetKey(OptionNames::ScriptSource), data_up->script_source); + + if (success) + found_something = true; StructuredData::Array *user_source; success = options_dict.GetValueForKeyAsArray(GetKey(OptionNames::UserSource), user_source); if (success) { + found_something = true; size_t num_elems = user_source->GetSize(); for (size_t i = 0; i < num_elems; i++) { std::string elem_string; success = user_source->GetItemAtIndexAsString(i, elem_string); if (success) - data->user_source.AppendString(elem_string); + data_up->user_source.AppendString(elem_string); } } - return std::unique_ptr(data); + + if (found_something) + return data_up; + else + return std::unique_ptr(); } const char *BreakpointOptions::g_option_names @@ -200,13 +213,13 @@ std::unique_ptr BreakpointOptions::CreateFromStructuredData( return nullptr; } - std::unique_ptr cmd_data; + std::unique_ptr cmd_data_up; StructuredData::Dictionary *cmds_dict; success = options_dict.GetValueForKeyAsDictionary( CommandData::GetSerializationKey(), cmds_dict); if (success && cmds_dict) { Error cmds_error; - cmd_data = CommandData::CreateFromStructuredData(*cmds_dict, cmds_error); + cmd_data_up = CommandData::CreateFromStructuredData(*cmds_dict, cmds_error); if (cmds_error.Fail()) { error.SetErrorStringWithFormat( "Failed to deserialize breakpoint command options: %s.", @@ -217,7 +230,8 @@ std::unique_ptr BreakpointOptions::CreateFromStructuredData( auto bp_options = llvm::make_unique( condition_text.c_str(), enabled, ignore_count, one_shot); - bp_options->SetCommandDataCallback(std::move(cmd_data)); + if (cmd_data_up.get()) + bp_options->SetCommandDataCallback(cmd_data_up); return bp_options; } @@ -306,6 +320,20 @@ bool BreakpointOptions::HasCallback() const { return m_callback != BreakpointOptions::NullCallback; } +bool BreakpointOptions::GetCommandLineCallbacks(StringList &command_list) { + if (!HasCallback()) + return false; + if (!m_baton_is_command_baton) + return false; + + auto cmd_baton = std::static_pointer_cast(m_callback_baton_sp); + CommandData *data = cmd_baton->getItem(); + if (!data) + return false; + command_list = data->user_source; + return true; +} + void BreakpointOptions::SetCondition(const char *condition) { if (!condition) condition = ""; @@ -418,7 +446,7 @@ void BreakpointOptions::CommandBaton::GetDescription( } void BreakpointOptions::SetCommandDataCallback( - std::unique_ptr cmd_data) { + std::unique_ptr &cmd_data) { auto baton_sp = std::make_shared(std::move(cmd_data)); SetCallback(BreakpointOptions::BreakpointOptionsCallbackFunction, baton_sp); } diff --git a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp index ed10a24..1850494 100644 --- a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp +++ b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp @@ -219,7 +219,7 @@ are no syntax errors may indicate that a function was declared but never called. auto cmd_data = llvm::make_unique(); cmd_data->user_source.SplitIntoLines(line.c_str(), line.size()); - bp_options->SetCommandDataCallback(std::move(cmd_data)); + bp_options->SetCommandDataCallback(cmd_data); } } @@ -251,7 +251,7 @@ are no syntax errors may indicate that a function was declared but never called. cmd_data->script_source.assign(oneliner); cmd_data->stop_on_error = m_options.m_stop_on_error; - bp_options->SetCommandDataCallback(std::move(cmd_data)); + bp_options->SetCommandDataCallback(cmd_data); } } -- 2.7.4