Check in an initial implementation of the "breakpoint clear" command, whose purpose is clear
the breakpoint associated with the (filename, line_number) combo when an arrow is pointing to
a source position using Emacs Grand Unified Debugger library to interact with lldb.
The current implmentation is insufficient in that it only asks the breakpoint whether it is
associated with a breakpoint resolver with FileLine type and whether it matches the (filename, line_number)
combo. There are other breakpoint resolver types whose breakpoint locations can potentially
match the (filename, line_number) combo.
The BreakpointResolver, BreakpointResolverName, BreakpointResolverAddress, and BreakpointResolverFileLine
classes have extra static classof methods to support LLVM style type inquiry through isa, cast, and dyn_cast.
The Breakpoint class has an API method bool GetMatchingFileLine(...) which is invoked from CommandObjectBreak.cpp
to implement the "breakpoint clear" command.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@117562 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Commands/CommandObjectBreakpoint.cpp b/source/Commands/CommandObjectBreakpoint.cpp
index 7894f55..237ac89 100644
--- a/source/Commands/CommandObjectBreakpoint.cpp
+++ b/source/Commands/CommandObjectBreakpoint.cpp
@@ -28,6 +28,8 @@
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadSpec.h"
+#include <vector>
+
using namespace lldb;
using namespace lldb_private;
@@ -526,23 +528,27 @@
bool status;
CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
- CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
+ CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
+ CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
- command_command_object->SetCommandName ("breakpoint command");
+ list_command_object->SetCommandName ("breakpoint list");
enable_command_object->SetCommandName("breakpoint enable");
disable_command_object->SetCommandName("breakpoint disable");
- list_command_object->SetCommandName ("breakpoint list");
- modify_command_object->SetCommandName ("breakpoint modify");
+ clear_command_object->SetCommandName("breakpoint clear");
+ delete_command_object->SetCommandName("breakpoint delete");
set_command_object->SetCommandName("breakpoint set");
+ command_command_object->SetCommandName ("breakpoint command");
+ modify_command_object->SetCommandName ("breakpoint modify");
status = LoadSubCommand ("list", list_command_object);
status = LoadSubCommand ("enable", enable_command_object);
status = LoadSubCommand ("disable", disable_command_object);
+ status = LoadSubCommand ("clear", clear_command_object);
status = LoadSubCommand ("delete", delete_command_object);
status = LoadSubCommand ("set", set_command_object);
status = LoadSubCommand ("command", command_command_object);
@@ -1039,6 +1045,189 @@
}
//-------------------------------------------------------------------------
+// CommandObjectBreakpointClear::CommandOptions
+//-------------------------------------------------------------------------
+#pragma mark Clear::CommandOptions
+
+CommandObjectBreakpointClear::CommandOptions::CommandOptions() :
+ Options (),
+ m_filename (),
+ m_line_num (0)
+{
+}
+
+CommandObjectBreakpointClear::CommandOptions::~CommandOptions ()
+{
+}
+
+lldb::OptionDefinition
+CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
+{
+ { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
+ "Specify the breakpoint by source location in this particular file."},
+
+ { LLDB_OPT_SET_1, true, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
+ "Specify the breakpoint by source location at this particular line."},
+
+ { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
+};
+
+const lldb::OptionDefinition*
+CommandObjectBreakpointClear::CommandOptions::GetDefinitions ()
+{
+ return g_option_table;
+}
+
+Error
+CommandObjectBreakpointClear::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
+{
+ Error error;
+ char short_option = (char) m_getopt_table[option_idx].val;
+
+ switch (short_option)
+ {
+ case 'f':
+ m_filename = option_arg;
+ break;
+
+ case 'l':
+ m_line_num = Args::StringToUInt32 (option_arg, 0);
+ break;
+
+ default:
+ error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
+ break;
+ }
+
+ return error;
+}
+
+void
+CommandObjectBreakpointClear::CommandOptions::ResetOptionValues ()
+{
+ Options::ResetOptionValues();
+
+ m_filename.clear();
+ m_line_num = 0;
+}
+
+//-------------------------------------------------------------------------
+// CommandObjectBreakpointClear
+//-------------------------------------------------------------------------
+#pragma mark Clear
+
+CommandObjectBreakpointClear::CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
+ CommandObject (interpreter,
+ "breakpoint clear",
+ "Clears a breakpoint or set of breakpoints in the executable.",
+ "breakpoint clear <cmd-options>")
+{
+}
+
+CommandObjectBreakpointClear::~CommandObjectBreakpointClear ()
+{
+}
+
+Options *
+CommandObjectBreakpointClear::GetOptions ()
+{
+ return &m_options;
+}
+
+bool
+CommandObjectBreakpointClear::Execute
+(
+ Args& command,
+ CommandReturnObject &result
+)
+{
+ Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
+ if (target == NULL)
+ {
+ result.AppendError ("Invalid target. No existing target or breakpoints.");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ // The following are the various types of breakpoints that could be cleared:
+ // 1). -f -l (clearing breakpoint by source location)
+
+ BreakpointClearType break_type = eClearTypeInvalid;
+
+ if (m_options.m_line_num != 0)
+ break_type = eClearTypeFileAndLine;
+
+ Mutex::Locker locker;
+ target->GetBreakpointList().GetListMutex(locker);
+
+ BreakpointList &breakpoints = target->GetBreakpointList();
+ size_t num_breakpoints = breakpoints.GetSize();
+
+ // Early return if there's no breakpoint at all.
+ if (num_breakpoints == 0)
+ {
+ result.AppendError ("Breakpoint clear: No breakpoint cleared.");
+ result.SetStatus (eReturnStatusFailed);
+ return result.Succeeded();
+ }
+
+ // Find matching breakpoints and delete them.
+
+ // First create a copy of all the IDs.
+ std::vector<break_id_t> BreakIDs;
+ for (size_t i = 0; i < num_breakpoints; ++i)
+ BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID());
+
+ int num_cleared = 0;
+ StreamString ss;
+ switch (break_type)
+ {
+ case eClearTypeFileAndLine: // Breakpoint by source position
+ {
+ const ConstString filename(m_options.m_filename.c_str());
+ BreakpointLocationCollection loc_coll;
+
+ for (size_t i = 0; i < num_breakpoints; ++i)
+ {
+ Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
+
+ if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
+ {
+ // If the collection size is 0, it's a full match and we can just remove the breakpoint.
+ if (loc_coll.GetSize() == 0)
+ {
+ bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
+ ss.EOL();
+ target->RemoveBreakpointByID (bp->GetID());
+ ++num_cleared;
+ }
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (num_cleared > 0)
+ {
+ StreamString &output_stream = result.GetOutputStream();
+ output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
+ output_stream << ss.GetData();
+ output_stream.EOL();
+ result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ }
+ else
+ {
+ result.AppendError ("Breakpoint clear: No breakpoint cleared.");
+ result.SetStatus (eReturnStatusFailed);
+ }
+
+ return result.Succeeded();
+}
+
+//-------------------------------------------------------------------------
// CommandObjectBreakpointDelete
//-------------------------------------------------------------------------
#pragma mark Delete