diff options
author | Johnny Chen <johnny.chen@apple.com> | 2010-10-28 17:27:46 +0000 |
---|---|---|
committer | Johnny Chen <johnny.chen@apple.com> | 2010-10-28 17:27:46 +0000 |
commit | b7234e40140cffea4868a0952ef26f102100a3fd (patch) | |
tree | 1ef37bfb6bef10455dbd52d73e64b0e608dc1064 /lldb/source/Commands/CommandObjectBreakpoint.cpp | |
parent | 8e0073008a29615b1749af4128c49c07cf77c200 (diff) | |
download | bcm5719-llvm-b7234e40140cffea4868a0952ef26f102100a3fd.tar.gz bcm5719-llvm-b7234e40140cffea4868a0952ef26f102100a3fd.zip |
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.
llvm-svn: 117562
Diffstat (limited to 'lldb/source/Commands/CommandObjectBreakpoint.cpp')
-rw-r--r-- | lldb/source/Commands/CommandObjectBreakpoint.cpp | 197 |
1 files changed, 193 insertions, 4 deletions
diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp index 7894f55c313..237ac89a35e 100644 --- a/lldb/source/Commands/CommandObjectBreakpoint.cpp +++ b/lldb/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 @@ CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInter 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 @@ CommandObjectBreakpointDisable::Execute } //------------------------------------------------------------------------- +// 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 |