From e9632ebab351b55cd0d400752288db7461bb2af4 Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Fri, 15 Sep 2017 00:52:35 +0000 Subject: [PATCH] Wire up the breakpoint name help string. llvm-svn: 313327 --- lldb/include/lldb/API/SBBreakpointName.h | 3 +++ .../breakpoint_names/TestBreakpointNames.py | 27 +++++++++++++++---- lldb/scripts/interface/SBBreakpointName.i | 3 +++ lldb/source/API/SBBreakpointName.cpp | 24 +++++++++++++++++ lldb/source/API/SBTarget.cpp | 3 --- lldb/source/Breakpoint/BreakpointName.cpp | 3 +++ .../Commands/CommandObjectBreakpoint.cpp | 18 ++++++++++--- 7 files changed, 69 insertions(+), 12 deletions(-) diff --git a/lldb/include/lldb/API/SBBreakpointName.h b/lldb/include/lldb/API/SBBreakpointName.h index 34d7db0d7dad..321f0d784d6f 100644 --- a/lldb/include/lldb/API/SBBreakpointName.h +++ b/lldb/include/lldb/API/SBBreakpointName.h @@ -90,6 +90,9 @@ public: SBError SetScriptCallbackBody(const char *script_body_text); + const char *GetHelpString() const; + void SetHelpString(const char *help_string); + bool GetAllowList() const; void SetAllowList(bool value); diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_names/TestBreakpointNames.py b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_names/TestBreakpointNames.py index a758f76cc570..b95d2cea550a 100644 --- a/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_names/TestBreakpointNames.py +++ b/lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_names/TestBreakpointNames.py @@ -92,6 +92,7 @@ class BreakpointNames(TestBase): self.cmd_list = lldb.SBStringList() self.cmd_list.AppendString("frame var") self.cmd_list.AppendString("bt") + self.help_string = "I do something interesting" def do_check_names(self): @@ -256,7 +257,7 @@ class BreakpointNames(TestBase): self.assertEqual(bkpt.GetAutoContinue(), new_auto_continue, "Option didn't propagate to the breakpoint.") # Now make this same breakpoint name - but from the command line - cmd_str = "breakpoint name configure %s -o %d -i %d -c '%s' -G %d -t %d -x %d -T '%s' -q '%s'"%(cl_bp_name_string, + cmd_str = "breakpoint name configure %s -o %d -i %d -c '%s' -G %d -t %d -x %d -T '%s' -q '%s' -H '%s'"%(cl_bp_name_string, self.is_one_shot, self.ignore_count, self.condition, @@ -264,16 +265,21 @@ class BreakpointNames(TestBase): self.tid, self.tidx, self.thread_name, - self.queue_name) + self.queue_name, + self.help_string) for cmd in self.cmd_list: cmd_str += " -C '%s'"%(cmd) - result = lldb.SBCommandReturnObject() - self.dbg.GetCommandInterpreter().HandleCommand(cmd_str, result) - self.assertTrue(result.Succeeded()) + self.runCmd(cmd_str, check=True) # Now look up this name again and check its options: cl_name = lldb.SBBreakpointName(self.target, cl_bp_name_string) self.check_option_values(cl_name) + # Also check the help string: + self.assertEqual(self.help_string, cl_name.GetHelpString(), "Help string didn't match") + # Change the name and make sure that works: + new_help = "I do something even more interesting" + cl_name.SetHelpString(new_help) + self.assertEqual(new_help, cl_name.GetHelpString(), "SetHelpString didn't") # We should have three names now, make sure the target can list them: name_list = lldb.SBStringList() @@ -281,6 +287,15 @@ class BreakpointNames(TestBase): for name_string in [self.bp_name_string, other_bp_name_string, cl_bp_name_string]: self.assertTrue(name_string in name_list, "Didn't find %s in names"%(name_string)) + # Delete the name from the current target. Make sure that works and deletes the + # name from the breakpoint as well: + self.target.DeleteBreakpointName(self.bp_name_string) + name_list.Clear() + self.target.GetBreakpointNames(name_list) + self.assertTrue(self.bp_name_string not in name_list, "Didn't delete %s from a real target"%(self.bp_name_string)) + # Also make sure the name got removed from breakpoints holding it: + self.assertFalse(bkpt.MatchesName(self.bp_name_string), "Didn't remove the name from the breakpoint.") + # Test that deleting the name we injected into the dummy target works (there's also a # cleanup that will do this, but that won't test the result... dummy_target = self.dbg.GetDummyTarget() @@ -288,6 +303,8 @@ class BreakpointNames(TestBase): name_list.Clear() dummy_target.GetBreakpointNames(name_list) self.assertTrue(self.bp_name_string not in name_list, "Didn't delete %s from the dummy target"%(self.bp_name_string)) + # Also make sure the name got removed from breakpoints holding it: + self.assertFalse(bkpt.MatchesName(self.bp_name_string), "Didn't remove the name from the breakpoint.") def check_permission_results(self, bp_name): self.assertEqual(bp_name.GetAllowDelete(), False, "Didn't set allow delete.") diff --git a/lldb/scripts/interface/SBBreakpointName.i b/lldb/scripts/interface/SBBreakpointName.i index 76f087cb3145..dbc078b94adf 100644 --- a/lldb/scripts/interface/SBBreakpointName.i +++ b/lldb/scripts/interface/SBBreakpointName.i @@ -91,6 +91,9 @@ public: SBError SetScriptCallbackBody(const char *script_body_text); + const char *GetHelpString() const; + void SetHelpString(const char *help_string); + bool GetAllowList() const; void SetAllowList(bool value); diff --git a/lldb/source/API/SBBreakpointName.cpp b/lldb/source/API/SBBreakpointName.cpp index b2ed5e71699d..22f0a45b4656 100644 --- a/lldb/source/API/SBBreakpointName.cpp +++ b/lldb/source/API/SBBreakpointName.cpp @@ -503,6 +503,30 @@ bool SBBreakpointName::GetCommandLineCommands(SBStringList &commands) { return has_commands; } +const char *SBBreakpointName::GetHelpString() const { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + + BreakpointName *bp_name = GetBreakpointName(); + if (!bp_name) + return ""; + + LLDB_LOG(log, "Help: {0}\n", bp_name->GetHelp()); + return bp_name->GetHelp(); +} + +void SBBreakpointName::SetHelpString(const char *help_string) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + BreakpointName *bp_name = GetBreakpointName(); + if (!bp_name) + return; + + LLDB_LOG(log, "Name: {0} help: {1}\n", bp_name->GetName(), help_string); + + std::lock_guard guard( + m_impl_up->GetTarget()->GetAPIMutex()); + bp_name->SetHelp(help_string); +} + bool SBBreakpointName::GetDescription(SBStream &s) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp index 93869d71c623..4b9c64f70f5d 100644 --- a/lldb/source/API/SBTarget.cpp +++ b/lldb/source/API/SBTarget.cpp @@ -1107,10 +1107,7 @@ void SBTarget::DeleteBreakpointName(const char *name) TargetSP target_sp(GetSP()); if (target_sp) { std::lock_guard guard(target_sp->GetAPIMutex()); - - std::vector name_vec; target_sp->DeleteBreakpointName(ConstString(name)); - } } diff --git a/lldb/source/Breakpoint/BreakpointName.cpp b/lldb/source/Breakpoint/BreakpointName.cpp index 7b9a2acfbc4a..be4710d7849c 100644 --- a/lldb/source/Breakpoint/BreakpointName.cpp +++ b/lldb/source/Breakpoint/BreakpointName.cpp @@ -60,6 +60,9 @@ bool BreakpointName::Permissions::GetDescription(Stream *s, bool BreakpointName::GetDescription(Stream *s, lldb::DescriptionLevel level) { bool printed_any = false; + if (!m_help.empty()) + s->Printf("Help: %s\n", m_help.c_str()); + if (GetOptions().AnySet()) { s->PutCString("Options: \n"); diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp index f4276e4e979c..5a175d61060e 100644 --- a/lldb/source/Commands/CommandObjectBreakpoint.cpp +++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp @@ -1687,9 +1687,10 @@ private: static OptionDefinition g_breakpoint_name_options[] = { // clang-format off - {LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."}, - {LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointID, "Specify a breakpoint ID to use."}, + {LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."}, + {LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointID, "Specify a breakpoint ID to use."}, {LLDB_OPT_SET_3, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, + {LLDB_OPT_SET_4, false, "help-string", 'H', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "A help string describing the purpose of this name."}, // clang-format on }; class BreakpointNameOptionGroup : public OptionGroup { @@ -1715,7 +1716,6 @@ public: error.Success()) m_name.SetValueFromString(option_arg); break; - case 'B': if (m_breakpoint.SetValueFromString(option_arg).Fail()) error.SetErrorStringWithFormat( @@ -1728,6 +1728,9 @@ public: "unrecognized value \"%s\" for use-dummy", option_arg.str().c_str()); break; + case 'H': + m_help_string.SetValueFromString(option_arg); + break; default: error.SetErrorStringWithFormat("unrecognized short option '%c'", @@ -1742,11 +1745,13 @@ public: m_breakpoint.Clear(); m_use_dummy.Clear(); m_use_dummy.SetDefaultValue(false); + m_help_string.Clear(); } OptionValueString m_name; OptionValueUInt64 m_breakpoint; OptionValueBoolean m_use_dummy; + OptionValueString m_help_string; }; static OptionDefinition g_breakpoint_access_options[] = { @@ -1849,7 +1854,9 @@ public: m_option_group.Append(&m_access_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_ALL); - m_option_group.Append(&m_bp_id, LLDB_OPT_SET_2, LLDB_OPT_SET_2); + m_option_group.Append(&m_bp_id, + LLDB_OPT_SET_2|LLDB_OPT_SET_4, + LLDB_OPT_SET_ALL); m_option_group.Finalize(); } @@ -1912,6 +1919,9 @@ protected: BreakpointName *bp_name = target->FindBreakpointName(name, true, error); if (!bp_name) continue; + if (m_bp_id.m_help_string.OptionWasSet()) + bp_name->SetHelp(m_bp_id.m_help_string.GetStringValue().str().c_str()); + if (bp_sp) target->ConfigureBreakpointName(*bp_name, *bp_sp->GetOptions(),