14 #include "llvm/ADT/StringRef.h"
41 bool process_is_valid =
43 if (!process_is_valid) {
44 result.
AppendError(
"There's no process or it is not alive.");
52 static const char *
RSA[4] = {
"-",
"to",
"To",
"TO"};
58 for (i = 0; i < 4; ++i)
59 if (Arg.contains(
RSA[i]))
66 bool CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
67 Target *target,
Args &args, std::vector<uint32_t> &wp_ids) {
70 if (target ==
nullptr)
74 wp_ids.push_back(watch_sp->GetID());
80 llvm::StringRef Minus(
"-");
81 std::vector<llvm::StringRef> StrRefArgs;
82 llvm::StringRef first;
83 llvm::StringRef second;
88 for (
auto &entry : args.
entries()) {
90 StrRefArgs.push_back(entry.ref());
94 std::tie(first, second) = entry.ref().split(
RSA[idx]);
96 StrRefArgs.push_back(first);
97 StrRefArgs.push_back(Minus);
99 StrRefArgs.push_back(second);
104 size_t size = StrRefArgs.size();
105 bool in_range =
false;
106 for (i = 0; i < size; ++i) {
107 llvm::StringRef Arg = StrRefArgs[i];
111 if (Arg.getAsInteger(0, end))
114 for (
id = beg;
id <= end; ++
id)
115 wp_ids.push_back(
id);
119 if (i < (size - 1) && StrRefArgs[i + 1] == Minus) {
120 if (Arg.getAsInteger(0, beg))
128 if (Arg.getAsInteger(0, beg))
130 wp_ids.push_back(beg);
140 #pragma mark List::CommandOptions
141 #define LLDB_OPTIONS_watchpoint_list
142 #include "CommandOptions.inc"
150 interpreter,
"watchpoint list",
151 "List all watchpoints at configurable levels of detail.", nullptr,
152 eCommandRequiresTarget) {
158 m_arguments.push_back(arg);
174 const int short_option = m_getopt_table[option_idx].val;
176 switch (short_option) {
187 llvm_unreachable(
"Unimplemented option");
198 return llvm::makeArrayRef(g_watchpoint_list_options);
208 Target *target = &GetSelectedTarget();
211 uint32_t num_supported_hardware_watchpoints;
213 num_supported_hardware_watchpoints);
216 "Number of supported hardware watchpoints: %u\n",
217 num_supported_hardware_watchpoints);
222 std::unique_lock<std::recursive_mutex> lock;
225 size_t num_watchpoints = watchpoints.
GetSize();
227 if (num_watchpoints == 0) {
238 for (
size_t i = 0; i < num_watchpoints; ++i) {
245 std::vector<uint32_t> wp_ids;
246 if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
247 target, command, wp_ids)) {
248 result.
AppendError(
"Invalid watchpoints specification.");
252 const size_t size = wp_ids.size();
253 for (
size_t i = 0; i < size; ++i) {
275 "Enable the specified disabled watchpoint(s). If "
276 "no watchpoints are specified, enable all of them.",
277 nullptr, eCommandRequiresTarget) {
283 m_arguments.push_back(arg);
291 CommandCompletions::InvokeCommonCompletionCallbacks(
292 GetCommandInterpreter(), CommandCompletions::eWatchPointIDCompletion,
298 Target *target = &GetSelectedTarget();
302 std::unique_lock<std::recursive_mutex> lock;
307 size_t num_watchpoints = watchpoints.
GetSize();
309 if (num_watchpoints == 0) {
310 result.
AppendError(
"No watchpoints exist to be enabled.");
319 (uint64_t)num_watchpoints);
323 std::vector<uint32_t> wp_ids;
324 if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
325 target, command, wp_ids)) {
326 result.
AppendError(
"Invalid watchpoints specification.");
331 const size_t size = wp_ids.size();
332 for (
size_t i = 0; i < size; ++i)
350 "Disable the specified watchpoint(s) without "
351 "removing it/them. If no watchpoints are "
352 "specified, disable them all.",
353 nullptr, eCommandRequiresTarget) {
359 m_arguments.push_back(arg);
367 CommandCompletions::InvokeCommonCompletionCallbacks(
368 GetCommandInterpreter(), CommandCompletions::eWatchPointIDCompletion,
374 Target *target = &GetSelectedTarget();
378 std::unique_lock<std::recursive_mutex> lock;
382 size_t num_watchpoints = watchpoints.
GetSize();
384 if (num_watchpoints == 0) {
385 result.
AppendError(
"No watchpoints exist to be disabled.");
394 (uint64_t)num_watchpoints);
397 result.
AppendError(
"Disable all watchpoints failed\n");
401 std::vector<uint32_t> wp_ids;
402 if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
403 target, command, wp_ids)) {
404 result.
AppendError(
"Invalid watchpoints specification.");
409 const size_t size = wp_ids.size();
410 for (
size_t i = 0; i < size; ++i)
422 #define LLDB_OPTIONS_watchpoint_delete
423 #include "CommandOptions.inc"
432 "Delete the specified watchpoint(s). If no "
433 "watchpoints are specified, delete them all.",
434 nullptr, eCommandRequiresTarget) {
440 m_arguments.push_back(arg);
448 CommandCompletions::InvokeCommonCompletionCallbacks(
449 GetCommandInterpreter(), CommandCompletions::eWatchPointIDCompletion,
463 const int short_option = m_getopt_table[option_idx].val;
465 switch (short_option) {
470 llvm_unreachable(
"Unimplemented option");
481 return llvm::makeArrayRef(g_watchpoint_delete_options);
485 bool m_force =
false;
490 Target *target = &GetSelectedTarget();
494 std::unique_lock<std::recursive_mutex> lock;
499 size_t num_watchpoints = watchpoints.
GetSize();
501 if (num_watchpoints == 0) {
502 result.
AppendError(
"No watchpoints exist to be deleted.");
506 if (command.
empty()) {
507 if (!m_options.m_force &&
508 !m_interpreter.Confirm(
509 "About to delete all watchpoints, do you want to do that?",
516 (uint64_t)num_watchpoints);
523 std::vector<uint32_t> wp_ids;
524 if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command,
526 result.
AppendError(
"Invalid watchpoints specification.");
531 const size_t size = wp_ids.size();
532 for (
size_t i = 0; i < size; ++i)
547 #pragma mark Ignore::CommandOptions
548 #define LLDB_OPTIONS_watchpoint_ignore
549 #include "CommandOptions.inc"
555 "Set ignore count on the specified watchpoint(s). "
556 "If no watchpoints are specified, set them all.",
557 nullptr, eCommandRequiresTarget) {
563 m_arguments.push_back(arg);
571 CommandCompletions::InvokeCommonCompletionCallbacks(
572 GetCommandInterpreter(), CommandCompletions::eWatchPointIDCompletion,
587 const int short_option = m_getopt_table[option_idx].val;
589 switch (short_option) {
591 if (option_arg.getAsInteger(0, m_ignore_count))
592 error.SetErrorStringWithFormat(
"invalid ignore count '%s'",
593 option_arg.str().c_str());
596 llvm_unreachable(
"Unimplemented option");
607 return llvm::makeArrayRef(g_watchpoint_ignore_options);
617 Target *target = &GetSelectedTarget();
621 std::unique_lock<std::recursive_mutex> lock;
626 size_t num_watchpoints = watchpoints.
GetSize();
628 if (num_watchpoints == 0) {
629 result.
AppendError(
"No watchpoints exist to be ignored.");
637 (uint64_t)num_watchpoints);
641 std::vector<uint32_t> wp_ids;
642 if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
643 target, command, wp_ids)) {
644 result.
AppendError(
"Invalid watchpoints specification.");
649 const size_t size = wp_ids.size();
650 for (
size_t i = 0; i < size; ++i)
666 #pragma mark Modify::CommandOptions
667 #define LLDB_OPTIONS_watchpoint_modify
668 #include "CommandOptions.inc"
676 interpreter,
"watchpoint modify",
677 "Modify the options on a watchpoint or set of watchpoints in the "
679 "If no watchpoint is specified, act on the last created "
681 "Passing an empty argument clears the modification.",
682 nullptr, eCommandRequiresTarget) {
688 m_arguments.push_back(arg);
696 CommandCompletions::InvokeCommonCompletionCallbacks(
697 GetCommandInterpreter(), CommandCompletions::eWatchPointIDCompletion,
712 const int short_option = m_getopt_table[option_idx].val;
714 switch (short_option) {
717 m_condition_passed =
true;
720 llvm_unreachable(
"Unimplemented option");
728 m_condition_passed =
false;
732 return llvm::makeArrayRef(g_watchpoint_modify_options);
738 bool m_condition_passed =
false;
743 Target *target = &GetSelectedTarget();
747 std::unique_lock<std::recursive_mutex> lock;
752 size_t num_watchpoints = watchpoints.
GetSize();
754 if (num_watchpoints == 0) {
755 result.
AppendError(
"No watchpoints exist to be modified.");
761 wp_sp->SetCondition(m_options.m_condition.c_str());
765 std::vector<uint32_t> wp_ids;
766 if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(
767 target, command, wp_ids)) {
768 result.
AppendError(
"Invalid watchpoints specification.");
773 const size_t size = wp_ids.size();
774 for (
size_t i = 0; i < size; ++i) {
775 WatchpointSP wp_sp = watchpoints.
FindByID(wp_ids[i]);
777 wp_sp->SetCondition(m_options.m_condition.c_str());
793 #pragma mark SetVariable
799 interpreter,
"watchpoint set variable",
800 "Set a watchpoint on a variable. "
801 "Use the '-w' option to specify the type of watchpoint and "
802 "the '-s' option to specify the byte size to watch for. "
803 "If no '-w' option is specified, it defaults to write. "
804 "If no '-s' option is specified, it defaults to the variable's "
806 "Note that there are limited hardware resources for watchpoints. "
807 "If watchpoint setting fails, consider disable/delete existing "
809 "to free up resources.",
811 eCommandRequiresFrame | eCommandTryTargetAPILock |
812 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {
817 (lldb) watchpoint set variable -w read_write my_global_var
820 " Watches my_global_var for read/write access, with the region to watch \
821 corresponding to the byte size of the data type.");
831 arg.push_back(var_name_arg);
834 m_arguments.push_back(arg);
839 m_option_group.Finalize();
849 CommandCompletions::InvokeCommonCompletionCallbacks(
850 GetCommandInterpreter(), CommandCompletions::eVariablePathCompletion,
854 Options *GetOptions()
override {
return &m_option_group; }
857 static size_t GetVariableCallback(
void *baton,
const char *name,
859 size_t old_size = variable_list.
GetSize();
864 return variable_list.
GetSize() - old_size;
868 Target *target = GetDebugger().GetSelectedTarget().get();
875 "specify your program variable to watch for");
880 if (!m_option_watchpoint.watch_type_specified) {
881 m_option_watchpoint.watch_type = OptionGroupWatchpoint::eWatchWrite;
890 ValueObjectSP valobj_sp;
895 result.
AppendError(
"specify exactly one variable to watch for");
902 StackFrame::eExpressionPathOptionCheckPtrVsMember |
903 StackFrame::eExpressionPathOptionsAllowDirectIVarAccess;
914 Status error(Variable::GetValuesForVariableExpressionPath(
916 m_exe_ctx.GetBestExecutionContextScope(), GetVariableCallback, target,
917 variable_list, valobj_list));
927 addr = valobj_sp->GetAddressOf(
false, &addr_type);
931 size = m_option_watchpoint.watch_size == 0
933 : m_option_watchpoint.watch_size;
935 compiler_type = valobj_sp->GetCompilerType();
937 const char *error_cstr =
error.AsCString(
nullptr);
942 "expression path that matches '%s'",
948 uint32_t watch_type = m_option_watchpoint.watch_type;
957 if (var_sp && var_sp->GetDeclaration().GetFile()) {
960 var_sp->GetDeclaration().DumpStopContext(&ss,
true);
963 output_stream.
Printf(
"Watchpoint created: ");
969 "Watchpoint creation failed (addr=0x%" PRIx64
", size=%" PRIu64
970 ", variable expression='%s').\n",
972 if (
error.AsCString(
nullptr))
991 interpreter,
"watchpoint set expression",
992 "Set a watchpoint on an address by supplying an expression. "
993 "Use the '-w' option to specify the type of watchpoint and "
994 "the '-s' option to specify the byte size to watch for. "
995 "If no '-w' option is specified, it defaults to write. "
996 "If no '-s' option is specified, it defaults to the target's "
997 "pointer byte size. "
998 "Note that there are limited hardware resources for watchpoints. "
999 "If watchpoint setting fails, consider disable/delete existing "
1001 "to free up resources.",
1003 eCommandRequiresFrame | eCommandTryTargetAPILock |
1004 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {
1009 (lldb) watchpoint set expression -w write -s 1 -- foo + 32
1011 Watches write access for the 1-byte region pointed to by the address 'foo + 32')");
1021 arg.push_back(expression_arg);
1024 m_arguments.push_back(arg);
1029 m_option_group.Finalize();
1036 bool WantsCompletion()
override {
return true; }
1038 Options *GetOptions()
override {
return &m_option_group; }
1041 bool DoExecute(llvm::StringRef raw_command,
1043 auto exe_ctx = GetCommandInterpreter().GetExecutionContext();
1047 Target *target = GetDebugger().GetSelectedTarget().get();
1052 llvm::StringRef expr = args.GetRawPart();
1055 if (!ParseOptionsAndNotify(args.GetArgs(), result, m_option_group,
1061 if (raw_command.trim().empty()) {
1062 result.
AppendError(
"required argument missing; specify an expression "
1063 "to evaluate into the address to watch for");
1068 if (!m_option_watchpoint.watch_type_specified) {
1069 m_option_watchpoint.watch_type = OptionGroupWatchpoint::eWatchWrite;
1077 ValueObjectSP valobj_sp;
1090 result.
AppendError(
"expression evaluation of address to watch failed");
1092 if (valobj_sp && !valobj_sp->GetError().Success())
1093 result.
AppendError(valobj_sp->GetError().AsCString());
1098 bool success =
false;
1099 addr = valobj_sp->GetValueAsUnsigned(0, &success);
1101 result.
AppendError(
"expression did not evaluate to an address");
1105 if (m_option_watchpoint.watch_size != 0)
1106 size = m_option_watchpoint.watch_size;
1111 uint32_t watch_type = m_option_watchpoint.watch_type;
1116 CompilerType compiler_type(valobj_sp->GetCompilerType());
1124 output_stream.
Printf(
"Watchpoint created: ");
1126 output_stream.
EOL();
1130 ", size=%" PRIu64
").\n",
1131 addr, (uint64_t)size);
1132 if (
error.AsCString(
nullptr))
1151 interpreter,
"watchpoint set",
"Commands for setting a watchpoint.",
1152 "watchpoint set <subcommand> [<subcommand-options>]") {
1166 #pragma mark MultiwordWatchpoint
1168 CommandObjectMultiwordWatchpoint::CommandObjectMultiwordWatchpoint(
1171 "Commands for operating on watchpoints.",
1172 "watchpoint <subcommand> [<command-options>]") {
1173 CommandObjectSP list_command_object(
1175 CommandObjectSP enable_command_object(
1177 CommandObjectSP disable_command_object(
1179 CommandObjectSP delete_command_object(
1181 CommandObjectSP ignore_command_object(
1183 CommandObjectSP command_command_object(
1185 CommandObjectSP modify_command_object(
1187 CommandObjectSP set_command_object(
1190 list_command_object->SetCommandName(
"watchpoint list");
1191 enable_command_object->SetCommandName(
"watchpoint enable");
1192 disable_command_object->SetCommandName(
"watchpoint disable");
1193 delete_command_object->SetCommandName(
"watchpoint delete");
1194 ignore_command_object->SetCommandName(
"watchpoint ignore");
1195 command_command_object->SetCommandName(
"watchpoint command");
1196 modify_command_object->SetCommandName(
"watchpoint modify");
1197 set_command_object->SetCommandName(
"watchpoint set");