diff options
Diffstat (limited to 'lldb/source/Commands/CommandObjectWatchpoint.cpp')
-rw-r--r-- | lldb/source/Commands/CommandObjectWatchpoint.cpp | 1834 |
1 files changed, 963 insertions, 871 deletions
diff --git a/lldb/source/Commands/CommandObjectWatchpoint.cpp b/lldb/source/Commands/CommandObjectWatchpoint.cpp index 0ac4576..8b6ff80 100644 --- a/lldb/source/Commands/CommandObjectWatchpoint.cpp +++ b/lldb/source/Commands/CommandObjectWatchpoint.cpp @@ -59,7 +59,30 @@ CheckTargetForWatchpointOperations(Target *target, CommandReturnObject &result) return true; } +// FIXME: This doesn't seem to be the right place for this functionality. #include "llvm/ADT/StringRef.h" +static inline void StripLeadingSpaces(llvm::StringRef &Str) +{ + while (!Str.empty() && isspace(Str[0])) + Str = Str.substr(1); +} +static inline llvm::StringRef StripOptionTerminator(llvm::StringRef &Str, bool with_dash_w, bool with_dash_x) +{ + llvm::StringRef ExprStr = Str; + + // Get rid of the leading spaces first. + StripLeadingSpaces(ExprStr); + + // If there's no '-w' and no '-x', we can just return. + if (!with_dash_w && !with_dash_x) + return ExprStr; + + // Otherwise, split on the "--" option terminator string, and return the rest of the string. + ExprStr = ExprStr.split("--").second; + StripLeadingSpaces(ExprStr); + return ExprStr; +} + // Equivalent class: {"-", "to", "To", "TO"} of range specifier array. static const char* RSA[4] = { "-", "to", "To", "TO" }; @@ -143,62 +166,174 @@ VerifyWatchpointIDs(Args &args, std::vector<uint32_t> &wp_ids) } //------------------------------------------------------------------------- -// CommandObjectMultiwordWatchpoint +// CommandObjectWatchpointList //------------------------------------------------------------------------- -#pragma mark MultiwordWatchpoint +#pragma mark List -CommandObjectMultiwordWatchpoint::CommandObjectMultiwordWatchpoint(CommandInterpreter &interpreter) : - CommandObjectMultiword (interpreter, - "watchpoint", - "A set of commands for operating on watchpoints.", - "watchpoint <command> [<command-options>]") +class CommandObjectWatchpointList : public CommandObjectParsed { - bool status; +public: + CommandObjectWatchpointList (CommandInterpreter &interpreter) : + CommandObjectParsed (interpreter, + "watchpoint list", + "List all watchpoints at configurable levels of detail.", + NULL), + m_options(interpreter) + { + CommandArgumentEntry arg; + CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange); + // Add the entry for the first argument for this command to the object's arguments vector. + m_arguments.push_back(arg); + } - CommandObjectSP list_command_object (new CommandObjectWatchpointList (interpreter)); - CommandObjectSP enable_command_object (new CommandObjectWatchpointEnable (interpreter)); - CommandObjectSP disable_command_object (new CommandObjectWatchpointDisable (interpreter)); - CommandObjectSP delete_command_object (new CommandObjectWatchpointDelete (interpreter)); - CommandObjectSP ignore_command_object (new CommandObjectWatchpointIgnore (interpreter)); - CommandObjectSP modify_command_object (new CommandObjectWatchpointModify (interpreter)); - CommandObjectSP set_command_object (new CommandObjectWatchpointSet (interpreter)); + virtual + ~CommandObjectWatchpointList () {} - list_command_object->SetCommandName ("watchpoint list"); - enable_command_object->SetCommandName("watchpoint enable"); - disable_command_object->SetCommandName("watchpoint disable"); - delete_command_object->SetCommandName("watchpoint delete"); - ignore_command_object->SetCommandName("watchpoint ignore"); - modify_command_object->SetCommandName("watchpoint modify"); - set_command_object->SetCommandName("watchpoint set"); + virtual Options * + GetOptions () + { + return &m_options; + } - status = LoadSubCommand ("list", list_command_object); - status = LoadSubCommand ("enable", enable_command_object); - status = LoadSubCommand ("disable", disable_command_object); - status = LoadSubCommand ("delete", delete_command_object); - status = LoadSubCommand ("ignore", ignore_command_object); - status = LoadSubCommand ("modify", modify_command_object); - status = LoadSubCommand ("set", set_command_object); -} + class CommandOptions : public Options + { + public: -CommandObjectMultiwordWatchpoint::~CommandObjectMultiwordWatchpoint() -{ -} + CommandOptions (CommandInterpreter &interpreter) : + Options(interpreter), + m_level(lldb::eDescriptionLevelBrief) // Watchpoint List defaults to brief descriptions + { + } + + virtual + ~CommandOptions () {} + + virtual Error + SetOptionValue (uint32_t option_idx, const char *option_arg) + { + Error error; + char short_option = (char) m_getopt_table[option_idx].val; + + switch (short_option) + { + case 'b': + m_level = lldb::eDescriptionLevelBrief; + break; + case 'f': + m_level = lldb::eDescriptionLevelFull; + break; + case 'v': + m_level = lldb::eDescriptionLevelVerbose; + break; + default: + error.SetErrorStringWithFormat("unrecognized option '%c'", short_option); + break; + } + + return error; + } + + void + OptionParsingStarting () + { + m_level = lldb::eDescriptionLevelFull; + } + + const OptionDefinition * + GetDefinitions () + { + return g_option_table; + } + + + // Options table: Required for subclasses of Options. + + static OptionDefinition g_option_table[]; + + // Instance variables to hold the values for command options. + + lldb::DescriptionLevel m_level; + }; + +protected: + virtual bool + DoExecute (Args& command, CommandReturnObject &result) + { + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + if (target == NULL) + { + result.AppendError ("Invalid target. No current target or watchpoints."); + result.SetStatus (eReturnStatusSuccessFinishNoResult); + return true; + } + + if (target->GetProcessSP() && target->GetProcessSP()->IsAlive()) + { + uint32_t num_supported_hardware_watchpoints; + Error error = target->GetProcessSP()->GetWatchpointSupportInfo(num_supported_hardware_watchpoints); + if (error.Success()) + result.AppendMessageWithFormat("Number of supported hardware watchpoints: %u\n", + num_supported_hardware_watchpoints); + } + + const WatchpointList &watchpoints = target->GetWatchpointList(); + Mutex::Locker locker; + target->GetWatchpointList().GetListMutex(locker); + + size_t num_watchpoints = watchpoints.GetSize(); + + if (num_watchpoints == 0) + { + result.AppendMessage("No watchpoints currently set."); + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return true; + } + + Stream &output_stream = result.GetOutputStream(); + + if (command.GetArgumentCount() == 0) + { + // No watchpoint selected; show info about all currently set watchpoints. + result.AppendMessage ("Current watchpoints:"); + for (size_t i = 0; i < num_watchpoints; ++i) + { + Watchpoint *wp = watchpoints.GetByIndex(i).get(); + AddWatchpointDescription(&output_stream, wp, m_options.m_level); + } + result.SetStatus(eReturnStatusSuccessFinishNoResult); + } + else + { + // Particular watchpoints selected; enable them. + std::vector<uint32_t> wp_ids; + if (!VerifyWatchpointIDs(command, wp_ids)) + { + result.AppendError("Invalid watchpoints specification."); + result.SetStatus(eReturnStatusFailed); + return false; + } + + const size_t size = wp_ids.size(); + for (size_t i = 0; i < size; ++i) + { + Watchpoint *wp = watchpoints.FindByID(wp_ids[i]).get(); + if (wp) + AddWatchpointDescription(&output_stream, wp, m_options.m_level); + result.SetStatus(eReturnStatusSuccessFinishNoResult); + } + } + + return result.Succeeded(); + } + +private: + CommandOptions m_options; +}; //------------------------------------------------------------------------- // CommandObjectWatchpointList::Options //------------------------------------------------------------------------- #pragma mark List::CommandOptions - -CommandObjectWatchpointList::CommandOptions::CommandOptions(CommandInterpreter &interpreter) : - Options(interpreter), - m_level(lldb::eDescriptionLevelBrief) // Watchpoint List defaults to brief descriptions -{ -} - -CommandObjectWatchpointList::CommandOptions::~CommandOptions() -{ -} - OptionDefinition CommandObjectWatchpointList::CommandOptions::g_option_table[] = { @@ -214,384 +349,396 @@ CommandObjectWatchpointList::CommandOptions::g_option_table[] = { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } }; -const OptionDefinition* -CommandObjectWatchpointList::CommandOptions::GetDefinitions() -{ - return g_option_table; -} +//------------------------------------------------------------------------- +// CommandObjectWatchpointEnable +//------------------------------------------------------------------------- +#pragma mark Enable -Error -CommandObjectWatchpointList::CommandOptions::SetOptionValue(uint32_t option_idx, const char *option_arg) +class CommandObjectWatchpointEnable : public CommandObjectParsed { - Error error; - char short_option = (char) m_getopt_table[option_idx].val; - - switch (short_option) +public: + CommandObjectWatchpointEnable (CommandInterpreter &interpreter) : + CommandObjectParsed (interpreter, + "enable", + "Enable the specified disabled watchpoint(s). If no watchpoints are specified, enable all of them.", + NULL) { - case 'b': - m_level = lldb::eDescriptionLevelBrief; - break; - case 'f': - m_level = lldb::eDescriptionLevelFull; - break; - case 'v': - m_level = lldb::eDescriptionLevelVerbose; - break; - default: - error.SetErrorStringWithFormat("unrecognized option '%c'", short_option); - break; + CommandArgumentEntry arg; + CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange); + // Add the entry for the first argument for this command to the object's arguments vector. + m_arguments.push_back(arg); } - return error; -} + virtual + ~CommandObjectWatchpointEnable () {} -void -CommandObjectWatchpointList::CommandOptions::OptionParsingStarting() -{ - m_level = lldb::eDescriptionLevelFull; -} +protected: + virtual bool + DoExecute (Args& command, + CommandReturnObject &result) + { + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + if (!CheckTargetForWatchpointOperations(target, result)) + return false; -//------------------------------------------------------------------------- -// CommandObjectWatchpointList -//------------------------------------------------------------------------- -#pragma mark List + Mutex::Locker locker; + target->GetWatchpointList().GetListMutex(locker); -CommandObjectWatchpointList::CommandObjectWatchpointList(CommandInterpreter &interpreter) : - CommandObject(interpreter, - "watchpoint list", - "List all watchpoints at configurable levels of detail.", - NULL), - m_options(interpreter) -{ - CommandArgumentEntry arg; - CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange); - // Add the entry for the first argument for this command to the object's arguments vector. - m_arguments.push_back(arg); -} + const WatchpointList &watchpoints = target->GetWatchpointList(); -CommandObjectWatchpointList::~CommandObjectWatchpointList() -{ -} + size_t num_watchpoints = watchpoints.GetSize(); -Options * -CommandObjectWatchpointList::GetOptions() -{ - return &m_options; -} + if (num_watchpoints == 0) + { + result.AppendError("No watchpoints exist to be enabled."); + result.SetStatus(eReturnStatusFailed); + return false; + } -bool -CommandObjectWatchpointList::Execute(Args& args, CommandReturnObject &result) -{ - Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); - if (target == NULL) - { - result.AppendError ("Invalid target. No current target or watchpoints."); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - return true; - } + if (command.GetArgumentCount() == 0) + { + // No watchpoint selected; enable all currently set watchpoints. + target->EnableAllWatchpoints(); + result.AppendMessageWithFormat("All watchpoints enabled. (%lu watchpoints)\n", num_watchpoints); + result.SetStatus(eReturnStatusSuccessFinishNoResult); + } + else + { + // Particular watchpoints selected; enable them. + std::vector<uint32_t> wp_ids; + if (!VerifyWatchpointIDs(command, wp_ids)) + { + result.AppendError("Invalid watchpoints specification."); + result.SetStatus(eReturnStatusFailed); + return false; + } - if (target->GetProcessSP() && target->GetProcessSP()->IsAlive()) - { - uint32_t num_supported_hardware_watchpoints; - Error error = target->GetProcessSP()->GetWatchpointSupportInfo(num_supported_hardware_watchpoints); - if (error.Success()) - result.AppendMessageWithFormat("Number of supported hardware watchpoints: %u\n", - num_supported_hardware_watchpoints); + int count = 0; + const size_t size = wp_ids.size(); + for (size_t i = 0; i < size; ++i) + if (target->EnableWatchpointByID(wp_ids[i])) + ++count; + result.AppendMessageWithFormat("%d watchpoints enabled.\n", count); + result.SetStatus(eReturnStatusSuccessFinishNoResult); + } + + return result.Succeeded(); } - const WatchpointList &watchpoints = target->GetWatchpointList(); - Mutex::Locker locker; - target->GetWatchpointList().GetListMutex(locker); +private: +}; - size_t num_watchpoints = watchpoints.GetSize(); +//------------------------------------------------------------------------- +// CommandObjectWatchpointDisable +//------------------------------------------------------------------------- +#pragma mark Disable - if (num_watchpoints == 0) +class CommandObjectWatchpointDisable : public CommandObjectParsed +{ +public: + CommandObjectWatchpointDisable (CommandInterpreter &interpreter) : + CommandObjectParsed (interpreter, + "watchpoint disable", + "Disable the specified watchpoint(s) without removing it/them. If no watchpoints are specified, disable them all.", + NULL) { - result.AppendMessage("No watchpoints currently set."); - result.SetStatus(eReturnStatusSuccessFinishNoResult); - return true; + CommandArgumentEntry arg; + CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange); + // Add the entry for the first argument for this command to the object's arguments vector. + m_arguments.push_back(arg); } - Stream &output_stream = result.GetOutputStream(); - if (args.GetArgumentCount() == 0) - { - // No watchpoint selected; show info about all currently set watchpoints. - result.AppendMessage ("Current watchpoints:"); - for (size_t i = 0; i < num_watchpoints; ++i) - { - Watchpoint *wp = watchpoints.GetByIndex(i).get(); - AddWatchpointDescription(&output_stream, wp, m_options.m_level); - } - result.SetStatus(eReturnStatusSuccessFinishNoResult); - } - else + virtual + ~CommandObjectWatchpointDisable () {} + +protected: + virtual bool + DoExecute (Args& command, CommandReturnObject &result) { - // Particular watchpoints selected; enable them. - std::vector<uint32_t> wp_ids; - if (!VerifyWatchpointIDs(args, wp_ids)) + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + if (!CheckTargetForWatchpointOperations(target, result)) + return false; + + Mutex::Locker locker; + target->GetWatchpointList().GetListMutex(locker); + + const WatchpointList &watchpoints = target->GetWatchpointList(); + size_t num_watchpoints = watchpoints.GetSize(); + + if (num_watchpoints == 0) { - result.AppendError("Invalid watchpoints specification."); + result.AppendError("No watchpoints exist to be disabled."); result.SetStatus(eReturnStatusFailed); return false; } - const size_t size = wp_ids.size(); - for (size_t i = 0; i < size; ++i) + if (command.GetArgumentCount() == 0) { - Watchpoint *wp = watchpoints.FindByID(wp_ids[i]).get(); - if (wp) - AddWatchpointDescription(&output_stream, wp, m_options.m_level); + // No watchpoint selected; disable all currently set watchpoints. + if (target->DisableAllWatchpoints()) + { + result.AppendMessageWithFormat("All watchpoints disabled. (%lu watchpoints)\n", num_watchpoints); + result.SetStatus(eReturnStatusSuccessFinishNoResult); + } + else + { + result.AppendError("Disable all watchpoints failed\n"); + result.SetStatus(eReturnStatusFailed); + } + } + else + { + // Particular watchpoints selected; disable them. + std::vector<uint32_t> wp_ids; + if (!VerifyWatchpointIDs(command, wp_ids)) + { + result.AppendError("Invalid watchpoints specification."); + result.SetStatus(eReturnStatusFailed); + return false; + } + + int count = 0; + const size_t size = wp_ids.size(); + for (size_t i = 0; i < size; ++i) + if (target->DisableWatchpointByID(wp_ids[i])) + ++count; + result.AppendMessageWithFormat("%d watchpoints disabled.\n", count); result.SetStatus(eReturnStatusSuccessFinishNoResult); } + + return result.Succeeded(); } - return result.Succeeded(); -} +}; //------------------------------------------------------------------------- -// CommandObjectWatchpointEnable +// CommandObjectWatchpointDelete //------------------------------------------------------------------------- -#pragma mark Enable - -CommandObjectWatchpointEnable::CommandObjectWatchpointEnable(CommandInterpreter &interpreter) : - CommandObject(interpreter, - "enable", - "Enable the specified disabled watchpoint(s). If no watchpoints are specified, enable all of them.", - NULL) -{ - CommandArgumentEntry arg; - CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange); - // Add the entry for the first argument for this command to the object's arguments vector. - m_arguments.push_back(arg); -} - -CommandObjectWatchpointEnable::~CommandObjectWatchpointEnable() -{ -} +#pragma mark Delete -bool -CommandObjectWatchpointEnable::Execute(Args& args, CommandReturnObject &result) +class CommandObjectWatchpointDelete : public CommandObjectParsed { - Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); - if (!CheckTargetForWatchpointOperations(target, result)) - return false; +public: + CommandObjectWatchpointDelete (CommandInterpreter &interpreter) : + CommandObjectParsed(interpreter, + "watchpoint delete", + "Delete the specified watchpoint(s). If no watchpoints are specified, delete them all.", + NULL) + { + CommandArgumentEntry arg; + CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange); + // Add the entry for the first argument for this command to the object's arguments vector. + m_arguments.push_back(arg); + } - Mutex::Locker locker; - target->GetWatchpointList().GetListMutex(locker); + virtual + ~CommandObjectWatchpointDelete () {} - const WatchpointList &watchpoints = target->GetWatchpointList(); +protected: + virtual bool + DoExecute (Args& command, CommandReturnObject &result) + { + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + if (!CheckTargetForWatchpointOperations(target, result)) + return false; - size_t num_watchpoints = watchpoints.GetSize(); + Mutex::Locker locker; + target->GetWatchpointList().GetListMutex(locker); + + const WatchpointList &watchpoints = target->GetWatchpointList(); - if (num_watchpoints == 0) - { - result.AppendError("No watchpoints exist to be enabled."); - result.SetStatus(eReturnStatusFailed); - return false; - } + size_t num_watchpoints = watchpoints.GetSize(); - if (args.GetArgumentCount() == 0) - { - // No watchpoint selected; enable all currently set watchpoints. - target->EnableAllWatchpoints(); - result.AppendMessageWithFormat("All watchpoints enabled. (%lu watchpoints)\n", num_watchpoints); - result.SetStatus(eReturnStatusSuccessFinishNoResult); - } - else - { - // Particular watchpoints selected; enable them. - std::vector<uint32_t> wp_ids; - if (!VerifyWatchpointIDs(args, wp_ids)) + if (num_watchpoints == 0) { - result.AppendError("Invalid watchpoints specification."); + result.AppendError("No watchpoints exist to be deleted."); result.SetStatus(eReturnStatusFailed); return false; } - int count = 0; - const size_t size = wp_ids.size(); - for (size_t i = 0; i < size; ++i) - if (target->EnableWatchpointByID(wp_ids[i])) - ++count; - result.AppendMessageWithFormat("%d watchpoints enabled.\n", count); - result.SetStatus(eReturnStatusSuccessFinishNoResult); + if (command.GetArgumentCount() == 0) + { + if (!m_interpreter.Confirm("About to delete all watchpoints, do you want to do that?", true)) + { + result.AppendMessage("Operation cancelled..."); + } + else + { + target->RemoveAllWatchpoints(); + result.AppendMessageWithFormat("All watchpoints removed. (%lu watchpoints)\n", num_watchpoints); + } + result.SetStatus (eReturnStatusSuccessFinishNoResult); + } + else + { + // Particular watchpoints selected; delete them. + std::vector<uint32_t> wp_ids; + if (!VerifyWatchpointIDs(command, wp_ids)) + { + result.AppendError("Invalid watchpoints specification."); + result.SetStatus(eReturnStatusFailed); + return false; + } + + int count = 0; + const size_t size = wp_ids.size(); + for (size_t i = 0; i < size; ++i) + if (target->RemoveWatchpointByID(wp_ids[i])) + ++count; + result.AppendMessageWithFormat("%d watchpoints deleted.\n",count); + result.SetStatus (eReturnStatusSuccessFinishNoResult); + } + + return result.Succeeded(); } - return result.Succeeded(); -} +}; //------------------------------------------------------------------------- -// CommandObjectWatchpointDisable +// CommandObjectWatchpointIgnore //------------------------------------------------------------------------- -#pragma mark Disable - -CommandObjectWatchpointDisable::CommandObjectWatchpointDisable(CommandInterpreter &interpreter) : - CommandObject(interpreter, - "watchpoint disable", - "Disable the specified watchpoint(s) without removing it/them. If no watchpoints are specified, disable them all.", - NULL) -{ - CommandArgumentEntry arg; - CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange); - // Add the entry for the first argument for this command to the object's arguments vector. - m_arguments.push_back(arg); -} -CommandObjectWatchpointDisable::~CommandObjectWatchpointDisable() +class CommandObjectWatchpointIgnore : public CommandObjectParsed { -} - -bool -CommandObjectWatchpointDisable::Execute(Args& args, CommandReturnObject &result) -{ - Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); - if (!CheckTargetForWatchpointOperations(target, result)) - return false; - - Mutex::Locker locker; - target->GetWatchpointList().GetListMutex(locker); +public: + CommandObjectWatchpointIgnore (CommandInterpreter &interpreter) : + CommandObjectParsed (interpreter, + "watchpoint ignore", + "Set ignore count on the specified watchpoint(s). If no watchpoints are specified, set them all.", + NULL), + m_options (interpreter) + { + CommandArgumentEntry arg; + CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange); + // Add the entry for the first argument for this command to the object's arguments vector. + m_arguments.push_back(arg); + } - const WatchpointList &watchpoints = target->GetWatchpointList(); - size_t num_watchpoints = watchpoints.GetSize(); + virtual + ~CommandObjectWatchpointIgnore () {} - if (num_watchpoints == 0) + virtual Options * + GetOptions () { - result.AppendError("No watchpoints exist to be disabled."); - result.SetStatus(eReturnStatusFailed); - return false; + return &m_options; } - if (args.GetArgumentCount() == 0) + class CommandOptions : public Options { - // No watchpoint selected; disable all currently set watchpoints. - if (target->DisableAllWatchpoints()) + public: + + CommandOptions (CommandInterpreter &interpreter) : + Options (interpreter), + m_ignore_count (0) { - result.AppendMessageWithFormat("All watchpoints disabled. (%lu watchpoints)\n", num_watchpoints); - result.SetStatus(eReturnStatusSuccessFinishNoResult); } - else + + virtual + ~CommandOptions () {} + + virtual Error + SetOptionValue (uint32_t option_idx, const char *option_arg) { - result.AppendError("Disable all watchpoints failed\n"); - result.SetStatus(eReturnStatusFailed); + Error error; + char short_option = (char) m_getopt_table[option_idx].val; + + switch (short_option) + { + case 'i': + { + m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0); + if (m_ignore_count == UINT32_MAX) + error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg); + } + break; + default: + error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); + break; + } + + return error; } - } - else - { - // Particular watchpoints selected; disable them. - std::vector<uint32_t> wp_ids; - if (!VerifyWatchpointIDs(args, wp_ids)) + + void + OptionParsingStarting () { - result.AppendError("Invalid watchpoints specification."); - result.SetStatus(eReturnStatusFailed); - return false; + m_ignore_count = 0; } - int count = 0; - const size_t size = wp_ids.size(); - for (size_t i = 0; i < size; ++i) - if (target->DisableWatchpointByID(wp_ids[i])) - ++count; - result.AppendMessageWithFormat("%d watchpoints disabled.\n", count); - result.SetStatus(eReturnStatusSuccessFinishNoResult); - } + const OptionDefinition * + GetDefinitions () + { + return g_option_table; + } - return result.Succeeded(); -} -//------------------------------------------------------------------------- -// CommandObjectWatchpointDelete -//------------------------------------------------------------------------- -#pragma mark Delete + // Options table: Required for subclasses of Options. -CommandObjectWatchpointDelete::CommandObjectWatchpointDelete(CommandInterpreter &interpreter) : - CommandObject(interpreter, - "watchpoint delete", - "Delete the specified watchpoint(s). If no watchpoints are specified, delete them all.", - NULL) -{ - CommandArgumentEntry arg; - CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange); - // Add the entry for the first argument for this command to the object's arguments vector. - m_arguments.push_back(arg); -} + static OptionDefinition g_option_table[]; -CommandObjectWatchpointDelete::~CommandObjectWatchpointDelete() -{ -} + // Instance variables to hold the values for command options. -bool -CommandObjectWatchpointDelete::Execute(Args& args, CommandReturnObject &result) -{ - Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); - if (!CheckTargetForWatchpointOperations(target, result)) - return false; + uint32_t m_ignore_count; + }; - Mutex::Locker locker; - target->GetWatchpointList().GetListMutex(locker); - - const WatchpointList &watchpoints = target->GetWatchpointList(); +protected: + virtual bool + DoExecute (Args& command, + CommandReturnObject &result) + { + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + if (!CheckTargetForWatchpointOperations(target, result)) + return false; - size_t num_watchpoints = watchpoints.GetSize(); + Mutex::Locker locker; + target->GetWatchpointList().GetListMutex(locker); + + const WatchpointList &watchpoints = target->GetWatchpointList(); - if (num_watchpoints == 0) - { - result.AppendError("No watchpoints exist to be deleted."); - result.SetStatus(eReturnStatusFailed); - return false; - } + size_t num_watchpoints = watchpoints.GetSize(); - if (args.GetArgumentCount() == 0) - { - if (!m_interpreter.Confirm("About to delete all watchpoints, do you want to do that?", true)) + if (num_watchpoints == 0) { - result.AppendMessage("Operation cancelled..."); + result.AppendError("No watchpoints exist to be ignored."); + result.SetStatus(eReturnStatusFailed); + return false; } - else + + if (command.GetArgumentCount() == 0) { - target->RemoveAllWatchpoints(); - result.AppendMessageWithFormat("All watchpoints removed. (%lu watchpoints)\n", num_watchpoints); + target->IgnoreAllWatchpoints(m_options.m_ignore_count); + result.AppendMessageWithFormat("All watchpoints ignored. (%lu watchpoints)\n", num_watchpoints); + result.SetStatus (eReturnStatusSuccessFinishNoResult); } - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - else - { - // Particular watchpoints selected; delete them. - std::vector<uint32_t> wp_ids; - if (!VerifyWatchpointIDs(args, wp_ids)) + else { - result.AppendError("Invalid watchpoints specification."); - result.SetStatus(eReturnStatusFailed); - return false; + // Particular watchpoints selected; ignore them. + std::vector<uint32_t> wp_ids; + if (!VerifyWatchpointIDs(command, wp_ids)) + { + result.AppendError("Invalid watchpoints specification."); + result.SetStatus(eReturnStatusFailed); + return false; + } + + int count = 0; + const size_t size = wp_ids.size(); + for (size_t i = 0; i < size; ++i) + if (target->IgnoreWatchpointByID(wp_ids[i], m_options.m_ignore_count)) + ++count; + result.AppendMessageWithFormat("%d watchpoints ignored.\n",count); + result.SetStatus (eReturnStatusSuccessFinishNoResult); } - int count = 0; - const size_t size = wp_ids.size(); - for (size_t i = 0; i < size; ++i) - if (target->RemoveWatchpointByID(wp_ids[i])) - ++count; - result.AppendMessageWithFormat("%d watchpoints deleted.\n",count); - result.SetStatus (eReturnStatusSuccessFinishNoResult); + return result.Succeeded(); } - return result.Succeeded(); -} +private: + CommandOptions m_options; +}; -//------------------------------------------------------------------------- -// CommandObjectWatchpointIgnore::CommandOptions -//------------------------------------------------------------------------- #pragma mark Ignore::CommandOptions - -CommandObjectWatchpointIgnore::CommandOptions::CommandOptions(CommandInterpreter &interpreter) : - Options (interpreter), - m_ignore_count (0) -{ -} - -CommandObjectWatchpointIgnore::CommandOptions::~CommandOptions () -{ -} - OptionDefinition CommandObjectWatchpointIgnore::CommandOptions::g_option_table[] = { @@ -599,135 +746,162 @@ CommandObjectWatchpointIgnore::CommandOptions::g_option_table[] = { 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL } }; -const OptionDefinition* -CommandObjectWatchpointIgnore::CommandOptions::GetDefinitions () -{ - return g_option_table; -} -Error -CommandObjectWatchpointIgnore::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg) +//------------------------------------------------------------------------- +// CommandObjectWatchpointModify +//------------------------------------------------------------------------- +#pragma mark Modify + +class CommandObjectWatchpointModify : public CommandObjectParsed { - Error error; - char short_option = (char) m_getopt_table[option_idx].val; +public: + + CommandObjectWatchpointModify (CommandInterpreter &interpreter) : + CommandObjectParsed (interpreter, + "watchpoint modify", + "Modify the options on a watchpoint or set of watchpoints in the executable. " + "If no watchpoint is specified, act on the last created watchpoint. " + "Passing an empty argument clears the modification.", + NULL), + m_options (interpreter) + { + CommandArgumentEntry arg; + CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange); + // Add the entry for the first argument for this command to the object's arguments vector. + m_arguments.push_back (arg); + } + + virtual + ~CommandObjectWatchpointModify () {} + + virtual Options * + GetOptions () + { + return &m_options; + } - switch (short_option) + class CommandOptions : public Options { - case 'i': + public: + + CommandOptions (CommandInterpreter &interpreter) : + Options (interpreter), + m_condition (), + m_condition_passed (false) { - m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0); - if (m_ignore_count == UINT32_MAX) - error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg); } - break; - default: - error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); - break; - } - return error; -} + virtual + ~CommandOptions () {} -void -CommandObjectWatchpointIgnore::CommandOptions::OptionParsingStarting () -{ - m_ignore_count = 0; -} + virtual Error + SetOptionValue (uint32_t option_idx, const char *option_arg) + { + Error error; + char short_option = (char) m_getopt_table[option_idx].val; -//------------------------------------------------------------------------- -// CommandObjectWatchpointIgnore -//------------------------------------------------------------------------- -#pragma mark Ignore - -CommandObjectWatchpointIgnore::CommandObjectWatchpointIgnore(CommandInterpreter &interpreter) : - CommandObject(interpreter, - "watchpoint ignore", - "Set ignore count on the specified watchpoint(s). If no watchpoints are specified, set them all.", - NULL), - m_options (interpreter) -{ - CommandArgumentEntry arg; - CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange); - // Add the entry for the first argument for this command to the object's arguments vector. - m_arguments.push_back(arg); -} + switch (short_option) + { + case 'c': + if (option_arg != NULL) + m_condition.assign (option_arg); + else + m_condition.clear(); + m_condition_passed = true; + break; + default: + error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); + break; + } -CommandObjectWatchpointIgnore::~CommandObjectWatchpointIgnore() -{ -} + return error; + } -Options * -CommandObjectWatchpointIgnore::GetOptions () -{ - return &m_options; -} + void + OptionParsingStarting () + { + m_condition.clear(); + m_condition_passed = false; + } + + const OptionDefinition* + GetDefinitions () + { + return g_option_table; + } -bool -CommandObjectWatchpointIgnore::Execute(Args& args, CommandReturnObject &result) -{ - Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); - if (!CheckTargetForWatchpointOperations(target, result)) - return false; + // Options table: Required for subclasses of Options. - Mutex::Locker locker; - target->GetWatchpointList().GetListMutex(locker); - - const WatchpointList &watchpoints = target->GetWatchpointList(); + static OptionDefinition g_option_table[]; - size_t num_watchpoints = watchpoints.GetSize(); + // Instance variables to hold the values for command options. - if (num_watchpoints == 0) - { - result.AppendError("No watchpoints exist to be ignored."); - result.SetStatus(eReturnStatusFailed); - return false; - } + std::string m_condition; + bool m_condition_passed; + }; - if (args.GetArgumentCount() == 0) - { - target->IgnoreAllWatchpoints(m_options.m_ignore_count); - result.AppendMessageWithFormat("All watchpoints ignored. (%lu watchpoints)\n", num_watchpoints); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - else +protected: + virtual bool + DoExecute (Args& command, CommandReturnObject &result) { - // Particular watchpoints selected; ignore them. - std::vector<uint32_t> wp_ids; - if (!VerifyWatchpointIDs(args, wp_ids)) + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + if (!CheckTargetForWatchpointOperations(target, result)) + return false; + + Mutex::Locker locker; + target->GetWatchpointList().GetListMutex(locker); + + const WatchpointList &watchpoints = target->GetWatchpointList(); + + size_t num_watchpoints = watchpoints.GetSize(); + + if (num_watchpoints == 0) { - result.AppendError("Invalid watchpoints specification."); + result.AppendError("No watchpoints exist to be modified."); result.SetStatus(eReturnStatusFailed); return false; } - int count = 0; - const size_t size = wp_ids.size(); - for (size_t i = 0; i < size; ++i) - if (target->IgnoreWatchpointByID(wp_ids[i], m_options.m_ignore_count)) - ++count; - result.AppendMessageWithFormat("%d watchpoints ignored.\n",count); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - - return result.Succeeded(); -} + if (command.GetArgumentCount() == 0) + { + WatchpointSP wp_sp = target->GetLastCreatedWatchpoint(); + wp_sp->SetCondition(m_options.m_condition.c_str()); + result.SetStatus (eReturnStatusSuccessFinishNoResult); + } + else + { + // Particular watchpoints selected; set condition on them. + std::vector<uint32_t> wp_ids; + if (!VerifyWatchpointIDs(command, wp_ids)) + { + result.AppendError("Invalid watchpoints specification."); + result.SetStatus(eReturnStatusFailed); + return false; + } -//------------------------------------------------------------------------- -// CommandObjectWatchpointModify::CommandOptions -//------------------------------------------------------------------------- -#pragma mark Modify::CommandOptions + int count = 0; + const size_t size = wp_ids.size(); + for (size_t i = 0; i < size; ++i) + { + WatchpointSP wp_sp = watchpoints.FindByID(wp_ids[i]); + if (wp_sp) + { + wp_sp->SetCondition(m_options.m_condition.c_str()); + ++count; + } + } + result.AppendMessageWithFormat("%d watchpoints modified.\n",count); + result.SetStatus (eReturnStatusSuccessFinishNoResult); + } -CommandObjectWatchpointModify::CommandOptions::CommandOptions(CommandInterpreter &interpreter) : - Options (interpreter), - m_condition (), - m_condition_passed (false) -{ -} + return result.Succeeded(); + } -CommandObjectWatchpointModify::CommandOptions::~CommandOptions () -{ -} +private: + CommandOptions m_options; +}; +#pragma mark Modify::CommandOptions OptionDefinition CommandObjectWatchpointModify::CommandOptions::g_option_table[] = { @@ -735,500 +909,418 @@ CommandObjectWatchpointModify::CommandOptions::g_option_table[] = { 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL } }; -const OptionDefinition* -CommandObjectWatchpointModify::CommandOptions::GetDefinitions () -{ - return g_option_table; -} - -Error -CommandObjectWatchpointModify::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg) -{ - Error error; - char short_option = (char) m_getopt_table[option_idx].val; - - switch (short_option) - { - case 'c': - if (option_arg != NULL) - m_condition.assign (option_arg); - else - m_condition.clear(); - m_condition_passed = true; - break; - default: - error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); - break; - } - - return error; -} - -void -CommandObjectWatchpointModify::CommandOptions::OptionParsingStarting () -{ - m_condition.clear(); - m_condition_passed = false; -} - //------------------------------------------------------------------------- -// CommandObjectWatchpointModify +// CommandObjectWatchpointSetVariable //------------------------------------------------------------------------- -#pragma mark Modify +#pragma mark SetVariable -CommandObjectWatchpointModify::CommandObjectWatchpointModify (CommandInterpreter &interpreter) : - CommandObject (interpreter, - "watchpoint modify", - "Modify the options on a watchpoint or set of watchpoints in the executable. " - "If no watchpoint is specified, act on the last created watchpoint. " - "Passing an empty argument clears the modification.", - NULL), - m_options (interpreter) +class CommandObjectWatchpointSetVariable : public CommandObjectParsed { - CommandArgumentEntry arg; - CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange); - // Add the entry for the first argument for this command to the object's arguments vector. - m_arguments.push_back (arg); -} - -CommandObjectWatchpointModify::~CommandObjectWatchpointModify () -{ -} - -Options * -CommandObjectWatchpointModify::GetOptions () -{ - return &m_options; -} - -bool -CommandObjectWatchpointModify::Execute -( - Args& args, - CommandReturnObject &result -) -{ - Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); - if (!CheckTargetForWatchpointOperations(target, result)) - return false; - - Mutex::Locker locker; - target->GetWatchpointList().GetListMutex(locker); - - const WatchpointList &watchpoints = target->GetWatchpointList(); - - size_t num_watchpoints = watchpoints.GetSize(); - - if (num_watchpoints == 0) +public: + + CommandObjectWatchpointSetVariable (CommandInterpreter &interpreter) : + CommandObjectParsed (interpreter, + "watchpoint set variable", + "Set a watchpoint on a variable. " + "Use the '-w' option to specify the type of watchpoint and " + "the '-x' option to specify the byte size to watch for. " + "If no '-w' option is specified, it defaults to read_write. " + "If no '-x' option is specified, it defaults to the variable's " + "byte size. " + "Note that there are limited hardware resources for watchpoints. " + "If watchpoint setting fails, consider disable/delete existing ones " + "to free up resources.", + NULL, + eFlagProcessMustBeLaunched | eFlagProcessMustBePaused), + m_option_group (interpreter), + m_option_watchpoint () { - result.AppendError("No watchpoints exist to be modified."); - result.SetStatus(eReturnStatusFailed); - return false; + SetHelpLong( + "Examples: \n\ + \n\ + watchpoint set variable -w read_wriate my_global_var \n\ + # Watch my_global_var for read/write access, with the region to watch corresponding to the byte size of the data type.\n"); + + CommandArgumentEntry arg; + CommandArgumentData var_name_arg; + + // Define the only variant of this arg. + var_name_arg.arg_type = eArgTypeVarName; + var_name_arg.arg_repetition = eArgRepeatPlain; + + // Push the variant into the argument entry. + arg.push_back (var_name_arg); + + // Push the data for the only argument into the m_arguments vector. + m_arguments.push_back (arg); + + // Absorb the '-w' and '-x' options into our option group. + m_option_group.Append (&m_option_watchpoint, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); + m_option_group.Finalize(); } - if (args.GetArgumentCount() == 0) + virtual + ~CommandObjectWatchpointSetVariable () {} + + virtual Options * + GetOptions () { - WatchpointSP wp_sp = target->GetLastCreatedWatchpoint(); - wp_sp->SetCondition(m_options.m_condition.c_str()); - result.SetStatus (eReturnStatusSuccessFinishNoResult); + return &m_option_group; } - else + +protected: + virtual bool + DoExecute (Args& command, + CommandReturnObject &result) { - // Particular watchpoints selected; set condition on them. - std::vector<uint32_t> wp_ids; - if (!VerifyWatchpointIDs(args, wp_ids)) + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); + StackFrame *frame = exe_ctx.GetFramePtr(); + if (frame == NULL) + { + result.AppendError ("you must be stopped in a valid stack frame to set a watchpoint."); + result.SetStatus (eReturnStatusFailed); + return false; + } + + // If no argument is present, issue an error message. There's no way to set a watchpoint. + if (command.GetArgumentCount() <= 0) { - result.AppendError("Invalid watchpoints specification."); + result.GetErrorStream().Printf("error: required argument missing; specify your program variable to watch for\n"); result.SetStatus(eReturnStatusFailed); return false; } - int count = 0; - const size_t size = wp_ids.size(); - for (size_t i = 0; i < size; ++i) + // If no '-w' is specified, default to '-w read_write'. + if (!m_option_watchpoint.watch_type_specified) { - WatchpointSP wp_sp = watchpoints.FindByID(wp_ids[i]); - if (wp_sp) - { - wp_sp->SetCondition(m_options.m_condition.c_str()); - ++count; - } + m_option_watchpoint.watch_type = OptionGroupWatchpoint::eWatchReadWrite; } - result.AppendMessageWithFormat("%d watchpoints modified.\n",count); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - return result.Succeeded(); -} + // We passed the sanity check for the command. + // Proceed to set the watchpoint now. + lldb::addr_t addr = 0; + size_t size = 0; -//------------------------------------------------------------------------- -// CommandObjectWatchpointSet -//------------------------------------------------------------------------- + VariableSP var_sp; + ValueObjectSP valobj_sp; + Stream &output_stream = result.GetOutputStream(); -CommandObjectWatchpointSet::CommandObjectWatchpointSet (CommandInterpreter &interpreter) : - CommandObjectMultiword (interpreter, - "watchpoint set", - "A set of commands for setting a watchpoint.", - "watchpoint set <subcommand> [<subcommand-options>]") -{ - - LoadSubCommand ("variable", CommandObjectSP (new CommandObjectWatchpointSetVariable (interpreter))); - LoadSubCommand ("expression", CommandObjectSP (new CommandObjectWatchpointSetExpression (interpreter))); -} + // A simple watch variable gesture allows only one argument. + if (command.GetArgumentCount() != 1) { + result.GetErrorStream().Printf("error: specify exactly one variable to watch for\n"); + result.SetStatus(eReturnStatusFailed); + return false; + } -CommandObjectWatchpointSet::~CommandObjectWatchpointSet () -{ -} + // Things have checked out ok... + Error error; + uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember; + valobj_sp = frame->GetValueForVariableExpressionPath (command.GetArgumentAtIndex(0), + eNoDynamicValues, + expr_path_options, + var_sp, + error); + if (valobj_sp) { + AddressType addr_type; + addr = valobj_sp->GetAddressOf(false, &addr_type); + if (addr_type == eAddressTypeLoad) { + // We're in business. + // Find out the size of this variable. + size = m_option_watchpoint.watch_size == 0 ? valobj_sp->GetByteSize() + : m_option_watchpoint.watch_size; + } + } else { + const char *error_cstr = error.AsCString(NULL); + if (error_cstr) + result.GetErrorStream().Printf("error: %s\n", error_cstr); + else + result.GetErrorStream().Printf ("error: unable to find any variable expression path that matches '%s'\n", + command.GetArgumentAtIndex(0)); + return false; + } + + // Now it's time to create the watchpoint. + uint32_t watch_type = m_option_watchpoint.watch_type; + error.Clear(); + Watchpoint *wp = target->CreateWatchpoint(addr, size, watch_type, error).get(); + if (wp) { + if (var_sp && var_sp->GetDeclaration().GetFile()) { + StreamString ss; + // True to show fullpath for declaration file. + var_sp->GetDeclaration().DumpStopContext(&ss, true); + wp->SetDeclInfo(ss.GetString()); + } + StreamString ss; + output_stream.Printf("Watchpoint created: "); + wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull); + output_stream.EOL(); + result.SetStatus(eReturnStatusSuccessFinishResult); + } else { + result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%llx, size=%lu).\n", + addr, size); + if (error.AsCString(NULL)) + result.AppendError(error.AsCString()); + result.SetStatus(eReturnStatusFailed); + } + + return result.Succeeded(); + } + +private: + OptionGroupOptions m_option_group; + OptionGroupWatchpoint m_option_watchpoint; +}; //------------------------------------------------------------------------- -// CommandObjectWatchpointSetVariable +// CommandObjectWatchpointSetExpression //------------------------------------------------------------------------- #pragma mark Set -CommandObjectWatchpointSetVariable::CommandObjectWatchpointSetVariable (CommandInterpreter &interpreter) : - CommandObject (interpreter, - "watchpoint set variable", - "Set a watchpoint on a variable. " - "Use the '-w' option to specify the type of watchpoint and " - "the '-x' option to specify the byte size to watch for. " - "If no '-w' option is specified, it defaults to read_write. " - "If no '-x' option is specified, it defaults to the variable's " - "byte size. " - "Note that there are limited hardware resources for watchpoints. " - "If watchpoint setting fails, consider disable/delete existing ones " - "to free up resources.", - NULL, - eFlagProcessMustBeLaunched | eFlagProcessMustBePaused), - m_option_group (interpreter), - m_option_watchpoint () +class CommandObjectWatchpointSetExpression : public CommandObjectRaw { - SetHelpLong( -"Examples: \n\ -\n\ - watchpoint set variable -w read_wriate my_global_var \n\ - # Watch my_global_var for read/write access, with the region to watch corresponding to the byte size of the data type.\n"); - - CommandArgumentEntry arg; - CommandArgumentData var_name_arg; - - // Define the only variant of this arg. - var_name_arg.arg_type = eArgTypeVarName; - var_name_arg.arg_repetition = eArgRepeatPlain; +public: + + CommandObjectWatchpointSetExpression (CommandInterpreter &interpreter) : + CommandObjectRaw (interpreter, + "watchpoint set expression", + "Set a watchpoint on an address by supplying an expression. " + "Use the '-w' option to specify the type of watchpoint and " + "the '-x' option to specify the byte size to watch for. " + "If no '-w' option is specified, it defaults to read_write. " + "If no '-x' option is specified, it defaults to the target's " + "pointer byte size. " + "Note that there are limited hardware resources for watchpoints. " + "If watchpoint setting fails, consider disable/delete existing ones " + "to free up resources.", + NULL, + eFlagProcessMustBeLaunched | eFlagProcessMustBePaused), + m_option_group (interpreter), + m_option_watchpoint () + { + SetHelpLong( + "Examples: \n\ + \n\ + watchpoint set expression -w write -x 1 -- foo + 32\n\ + # Watch write access for the 1-byte region pointed to by the address 'foo + 32'.\n"); + + CommandArgumentEntry arg; + CommandArgumentData expression_arg; + + // Define the only variant of this arg. + expression_arg.arg_type = eArgTypeExpression; + expression_arg.arg_repetition = eArgRepeatPlain; + + // Push the only variant into the argument entry. + arg.push_back (expression_arg); + + // Push the data for the only argument into the m_arguments vector. + m_arguments.push_back (arg); + + // Absorb the '-w' and '-x' options into our option group. + m_option_group.Append (&m_option_watchpoint, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); + m_option_group.Finalize(); + } - // Push the variant into the argument entry. - arg.push_back (var_name_arg); - - // Push the data for the only argument into the m_arguments vector. - m_arguments.push_back (arg); - // Absorb the '-w' and '-x' options into our option group. - m_option_group.Append (&m_option_watchpoint, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); - m_option_group.Finalize(); -} + virtual + ~CommandObjectWatchpointSetExpression () {} -CommandObjectWatchpointSetVariable::~CommandObjectWatchpointSetVariable () -{ -} - -Options * -CommandObjectWatchpointSetVariable::GetOptions () -{ - return &m_option_group; -} - -bool -CommandObjectWatchpointSetVariable::Execute -( - Args& command, - CommandReturnObject &result -) -{ - Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - StackFrame *frame = exe_ctx.GetFramePtr(); - if (frame == NULL) - { - result.AppendError ("you must be stopped in a valid stack frame to set a watchpoint."); - result.SetStatus (eReturnStatusFailed); - return false; - } + // Overrides base class's behavior where WantsCompletion = !WantsRawCommandString. + virtual bool + WantsCompletion() { return true; } - // If no argument is present, issue an error message. There's no way to set a watchpoint. - if (command.GetArgumentCount() <= 0) + virtual Options * + GetOptions () { - result.GetErrorStream().Printf("error: required argument missing; specify your program variable to watch for\n"); - result.SetStatus(eReturnStatusFailed); - return false; + return &m_option_group; } - // If no '-w' is specified, default to '-w read_write'. - if (!m_option_watchpoint.watch_type_specified) +protected: + virtual bool + DoExecute (const char *raw_command, CommandReturnObject &result) { - m_option_watchpoint.watch_type = OptionGroupWatchpoint::eWatchReadWrite; - } - - // We passed the sanity check for the command. - // Proceed to set the watchpoint now. - lldb::addr_t addr = 0; - size_t size = 0; + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); + StackFrame *frame = exe_ctx.GetFramePtr(); + if (frame == NULL) + { + result.AppendError ("you must be stopped in a valid stack frame to set a watchpoint."); + result.SetStatus (eReturnStatusFailed); + return false; + } - VariableSP var_sp; - ValueObjectSP valobj_sp; - Stream &output_stream = result.GetOutputStream(); + Args command(raw_command); - // A simple watch variable gesture allows only one argument. - if (command.GetArgumentCount() != 1) { - result.GetErrorStream().Printf("error: specify exactly one variable to watch for\n"); - result.SetStatus(eReturnStatusFailed); - return false; - } + // Process possible options. + if (!ParseOptions (command, result)) + return false; - // Things have checked out ok... - Error error; - uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember; - valobj_sp = frame->GetValueForVariableExpressionPath (command.GetArgumentAtIndex(0), - eNoDynamicValues, - expr_path_options, - var_sp, - error); - if (valobj_sp) { - AddressType addr_type; - addr = valobj_sp->GetAddressOf(false, &addr_type); - if (addr_type == eAddressTypeLoad) { - // We're in business. - // Find out the size of this variable. - size = m_option_watchpoint.watch_size == 0 ? valobj_sp->GetByteSize() - : m_option_watchpoint.watch_size; + // If no argument is present, issue an error message. There's no way to set a watchpoint. + if (command.GetArgumentCount() <= 0) + { + result.GetErrorStream().Printf("error: required argument missing; specify an expression to evaulate into the addres to watch for\n"); + result.SetStatus(eReturnStatusFailed); + return false; } - } else { - const char *error_cstr = error.AsCString(NULL); - if (error_cstr) - result.GetErrorStream().Printf("error: %s\n", error_cstr); - else - result.GetErrorStream().Printf ("error: unable to find any variable expression path that matches '%s'\n", - command.GetArgumentAtIndex(0)); - return false; - } - // Now it's time to create the watchpoint. - uint32_t watch_type = m_option_watchpoint.watch_type; - error.Clear(); - Watchpoint *wp = target->CreateWatchpoint(addr, size, watch_type, error).get(); - if (wp) { - if (var_sp && var_sp->GetDeclaration().GetFile()) { - StreamString ss; - // True to show fullpath for declaration file. - var_sp->GetDeclaration().DumpStopContext(&ss, true); - wp->SetDeclInfo(ss.GetString()); - } - StreamString ss; - output_stream.Printf("Watchpoint created: "); - wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull); - output_stream.EOL(); - result.SetStatus(eReturnStatusSuccessFinishResult); - } else { - result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%llx, size=%lu).\n", - addr, size); - if (error.AsCString(NULL)) - result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); - } + bool with_dash_w = m_option_watchpoint.watch_type_specified; + bool with_dash_x = (m_option_watchpoint.watch_size != 0); - return result.Succeeded(); -} + // If no '-w' is specified, default to '-w read_write'. + if (!with_dash_w) + { + m_option_watchpoint.watch_type = OptionGroupWatchpoint::eWatchReadWrite; + } -//------------------------------------------------------------------------- -// CommandObjectWatchpointSetExpression -//------------------------------------------------------------------------- -#pragma mark Set + // We passed the sanity check for the command. + // Proceed to set the watchpoint now. + lldb::addr_t addr = 0; + size_t size = 0; -CommandObjectWatchpointSetExpression::CommandObjectWatchpointSetExpression (CommandInterpreter &interpreter) : - CommandObject (interpreter, - "watchpoint set expression", - "Set a watchpoint on an address by supplying an expression. " - "Use the '-w' option to specify the type of watchpoint and " - "the '-x' option to specify the byte size to watch for. " - "If no '-w' option is specified, it defaults to read_write. " - "If no '-x' option is specified, it defaults to the target's " - "pointer byte size. " - "Note that there are limited hardware resources for watchpoints. " - "If watchpoint setting fails, consider disable/delete existing ones " - "to free up resources.", - NULL, - eFlagProcessMustBeLaunched | eFlagProcessMustBePaused), - m_option_group (interpreter), - m_option_watchpoint () -{ - SetHelpLong( -"Examples: \n\ -\n\ - watchpoint set expression -w write -x 1 -- foo + 32\n\ - # Watch write access for the 1-byte region pointed to by the address 'foo + 32'.\n"); - - CommandArgumentEntry arg; - CommandArgumentData expression_arg; - - // Define the only variant of this arg. - expression_arg.arg_type = eArgTypeExpression; - expression_arg.arg_repetition = eArgRepeatPlain; + VariableSP var_sp; + ValueObjectSP valobj_sp; + Stream &output_stream = result.GetOutputStream(); - // Push the only variant into the argument entry. - arg.push_back (expression_arg); - - // Push the data for the only argument into the m_arguments vector. - m_arguments.push_back (arg); + // We will process the raw command string to rid of the '-w', '-x', or '--' + llvm::StringRef raw_expr_str(raw_command); + std::string expr_str = StripOptionTerminator(raw_expr_str, with_dash_w, with_dash_x).str(); - // Absorb the '-w' and '-x' options into our option group. - m_option_group.Append (&m_option_watchpoint, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); - m_option_group.Finalize(); -} + // Sanity check for when the user forgets to terminate the option strings with a '--'. + if ((with_dash_w || with_dash_w) && expr_str.empty()) + { + result.GetErrorStream().Printf("error: did you forget to enter the option terminator string \"--\"?\n"); + result.SetStatus(eReturnStatusFailed); + return false; + } -CommandObjectWatchpointSetExpression::~CommandObjectWatchpointSetExpression () -{ -} + // Use expression evaluation to arrive at the address to watch. + const bool coerce_to_id = true; + const bool unwind_on_error = true; + const bool keep_in_memory = false; + ExecutionResults expr_result = target->EvaluateExpression (expr_str.c_str(), + frame, + eExecutionPolicyOnlyWhenNeeded, + coerce_to_id, + unwind_on_error, + keep_in_memory, + eNoDynamicValues, + valobj_sp); + if (expr_result != eExecutionCompleted) { + result.GetErrorStream().Printf("error: expression evaluation of address to watch failed\n"); + result.GetErrorStream().Printf("expression evaluated: %s\n", expr_str.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; + } -Options * -CommandObjectWatchpointSetExpression::GetOptions () -{ - return &m_option_group; -} + // Get the address to watch. + bool success = false; + addr = valobj_sp->GetValueAsUnsigned(0, &success); + if (!success) { + result.GetErrorStream().Printf("error: expression did not evaluate to an address\n"); + result.SetStatus(eReturnStatusFailed); + return false; + } + size = with_dash_x ? m_option_watchpoint.watch_size + : target->GetArchitecture().GetAddressByteSize(); + + // Now it's time to create the watchpoint. + uint32_t watch_type = m_option_watchpoint.watch_type; + Error error; + Watchpoint *wp = target->CreateWatchpoint(addr, size, watch_type, error).get(); + if (wp) { + if (var_sp && var_sp->GetDeclaration().GetFile()) { + StreamString ss; + // True to show fullpath for declaration file. + var_sp->GetDeclaration().DumpStopContext(&ss, true); + wp->SetDeclInfo(ss.GetString()); + } + StreamString ss; + output_stream.Printf("Watchpoint created: "); + wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull); + output_stream.EOL(); + result.SetStatus(eReturnStatusSuccessFinishResult); + } else { + result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%llx, size=%lu).\n", + addr, size); + if (error.AsCString(NULL)) + result.AppendError(error.AsCString()); + result.SetStatus(eReturnStatusFailed); + } -#include "llvm/ADT/StringRef.h" -static inline void StripLeadingSpaces(llvm::StringRef &Str) -{ - while (!Str.empty() && isspace(Str[0])) - Str = Str.substr(1); -} -static inline llvm::StringRef StripOptionTerminator(llvm::StringRef &Str, bool with_dash_w, bool with_dash_x) -{ - llvm::StringRef ExprStr = Str; + return result.Succeeded(); + } - // Get rid of the leading spaces first. - StripLeadingSpaces(ExprStr); +private: + OptionGroupOptions m_option_group; + OptionGroupWatchpoint m_option_watchpoint; +}; - // If there's no '-w' and no '-x', we can just return. - if (!with_dash_w && !with_dash_x) - return ExprStr; +//------------------------------------------------------------------------- +// CommandObjectWatchpointSet +//------------------------------------------------------------------------- +#pragma mark Set - // Otherwise, split on the "--" option terminator string, and return the rest of the string. - ExprStr = ExprStr.split("--").second; - StripLeadingSpaces(ExprStr); - return ExprStr; -} -bool -CommandObjectWatchpointSetExpression::ExecuteRawCommandString -( - const char *raw_command, - CommandReturnObject &result -) +class CommandObjectWatchpointSet : public CommandObjectMultiword { - Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - StackFrame *frame = exe_ctx.GetFramePtr(); - if (frame == NULL) - { - result.AppendError ("you must be stopped in a valid stack frame to set a watchpoint."); - result.SetStatus (eReturnStatusFailed); - return false; - } - - Args command(raw_command); +public: - // Process possible options. - if (!ParseOptions (command, result)) - return false; - - // If no argument is present, issue an error message. There's no way to set a watchpoint. - if (command.GetArgumentCount() <= 0) + CommandObjectWatchpointSet (CommandInterpreter &interpreter) : + CommandObjectMultiword (interpreter, + "watchpoint set", + "A set of commands for setting a watchpoint.", + "watchpoint set <subcommand> [<subcommand-options>]") { - result.GetErrorStream().Printf("error: required argument missing; specify an expression to evaulate into the addres to watch for\n"); - result.SetStatus(eReturnStatusFailed); - return false; + + LoadSubCommand ("variable", CommandObjectSP (new CommandObjectWatchpointSetVariable (interpreter))); + LoadSubCommand ("expression", CommandObjectSP (new CommandObjectWatchpointSetExpression (interpreter))); } - bool with_dash_w = m_option_watchpoint.watch_type_specified; - bool with_dash_x = (m_option_watchpoint.watch_size != 0); - // If no '-w' is specified, default to '-w read_write'. - if (!with_dash_w) - { - m_option_watchpoint.watch_type = OptionGroupWatchpoint::eWatchReadWrite; - } + virtual + ~CommandObjectWatchpointSet () {} - // We passed the sanity check for the command. - // Proceed to set the watchpoint now. - lldb::addr_t addr = 0; - size_t size = 0; +}; - VariableSP var_sp; - ValueObjectSP valobj_sp; - Stream &output_stream = result.GetOutputStream(); +//------------------------------------------------------------------------- +// CommandObjectMultiwordWatchpoint +//------------------------------------------------------------------------- +#pragma mark MultiwordWatchpoint - // We will process the raw command string to rid of the '-w', '-x', or '--' - llvm::StringRef raw_expr_str(raw_command); - std::string expr_str = StripOptionTerminator(raw_expr_str, with_dash_w, with_dash_x).str(); +CommandObjectMultiwordWatchpoint::CommandObjectMultiwordWatchpoint(CommandInterpreter &interpreter) : + CommandObjectMultiword (interpreter, + "watchpoint", + "A set of commands for operating on watchpoints.", + "watchpoint <command> [<command-options>]") +{ + bool status; - // Sanity check for when the user forgets to terminate the option strings with a '--'. - if ((with_dash_w || with_dash_w) && expr_str.empty()) - { - result.GetErrorStream().Printf("error: did you forget to enter the option terminator string \"--\"?\n"); - result.SetStatus(eReturnStatusFailed); - return false; - } + CommandObjectSP list_command_object (new CommandObjectWatchpointList (interpreter)); + CommandObjectSP enable_command_object (new CommandObjectWatchpointEnable (interpreter)); + CommandObjectSP disable_command_object (new CommandObjectWatchpointDisable (interpreter)); + CommandObjectSP delete_command_object (new CommandObjectWatchpointDelete (interpreter)); + CommandObjectSP ignore_command_object (new CommandObjectWatchpointIgnore (interpreter)); + CommandObjectSP modify_command_object (new CommandObjectWatchpointModify (interpreter)); + CommandObjectSP set_command_object (new CommandObjectWatchpointSet (interpreter)); - // Use expression evaluation to arrive at the address to watch. - const bool coerce_to_id = true; - const bool unwind_on_error = true; - const bool keep_in_memory = false; - ExecutionResults expr_result = target->EvaluateExpression (expr_str.c_str(), - frame, - eExecutionPolicyOnlyWhenNeeded, - coerce_to_id, - unwind_on_error, - keep_in_memory, - eNoDynamicValues, - valobj_sp); - if (expr_result != eExecutionCompleted) { - result.GetErrorStream().Printf("error: expression evaluation of address to watch failed\n"); - result.GetErrorStream().Printf("expression evaluated: %s\n", expr_str.c_str()); - result.SetStatus(eReturnStatusFailed); - return false; - } + list_command_object->SetCommandName ("watchpoint list"); + enable_command_object->SetCommandName("watchpoint enable"); + disable_command_object->SetCommandName("watchpoint disable"); + delete_command_object->SetCommandName("watchpoint delete"); + ignore_command_object->SetCommandName("watchpoint ignore"); + modify_command_object->SetCommandName("watchpoint modify"); + set_command_object->SetCommandName("watchpoint set"); - // Get the address to watch. - bool success = false; - addr = valobj_sp->GetValueAsUnsigned(0, &success); - if (!success) { - result.GetErrorStream().Printf("error: expression did not evaluate to an address\n"); - result.SetStatus(eReturnStatusFailed); - return false; - } - size = with_dash_x ? m_option_watchpoint.watch_size - : target->GetArchitecture().GetAddressByteSize(); - - // Now it's time to create the watchpoint. - uint32_t watch_type = m_option_watchpoint.watch_type; - Error error; - Watchpoint *wp = target->CreateWatchpoint(addr, size, watch_type, error).get(); - if (wp) { - if (var_sp && var_sp->GetDeclaration().GetFile()) { - StreamString ss; - // True to show fullpath for declaration file. - var_sp->GetDeclaration().DumpStopContext(&ss, true); - wp->SetDeclInfo(ss.GetString()); - } - StreamString ss; - output_stream.Printf("Watchpoint created: "); - wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull); - output_stream.EOL(); - result.SetStatus(eReturnStatusSuccessFinishResult); - } else { - result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%llx, size=%lu).\n", - addr, size); - if (error.AsCString(NULL)) - result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); - } + status = LoadSubCommand ("list", list_command_object); + status = LoadSubCommand ("enable", enable_command_object); + status = LoadSubCommand ("disable", disable_command_object); + status = LoadSubCommand ("delete", delete_command_object); + status = LoadSubCommand ("ignore", ignore_command_object); + status = LoadSubCommand ("modify", modify_command_object); + status = LoadSubCommand ("set", set_command_object); +} - return result.Succeeded(); +CommandObjectMultiwordWatchpoint::~CommandObjectMultiwordWatchpoint() +{ } + |