1 //===-- CommandObjectWatchpoint.cpp -----------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/lldb-python.h"
12 #include "CommandObjectWatchpoint.h"
13 #include "CommandObjectWatchpointCommand.h"
17 // Other libraries and framework includes
19 #include "lldb/Breakpoint/Watchpoint.h"
20 #include "lldb/Breakpoint/WatchpointList.h"
21 #include "lldb/Core/StreamString.h"
22 #include "lldb/Core/ValueObject.h"
23 #include "lldb/Core/ValueObjectVariable.h"
24 #include "lldb/Interpreter/CommandInterpreter.h"
25 #include "lldb/Interpreter/CommandReturnObject.h"
26 #include "lldb/Interpreter/CommandCompletions.h"
27 #include "lldb/Symbol/Variable.h"
28 #include "lldb/Symbol/VariableList.h"
29 #include "lldb/Target/Target.h"
34 using namespace lldb_private;
37 AddWatchpointDescription(Stream *s, Watchpoint *wp, lldb::DescriptionLevel level)
40 wp->GetDescription(s, level);
46 CheckTargetForWatchpointOperations(Target *target, CommandReturnObject &result)
50 result.AppendError ("Invalid target. No existing target or watchpoints.");
51 result.SetStatus (eReturnStatusFailed);
54 bool process_is_valid = target->GetProcessSP() && target->GetProcessSP()->IsAlive();
55 if (!process_is_valid)
57 result.AppendError ("Thre's no process or it is not alive.");
58 result.SetStatus (eReturnStatusFailed);
61 // Target passes our checks, return true.
65 // FIXME: This doesn't seem to be the right place for this functionality.
66 #include "llvm/ADT/StringRef.h"
67 static inline void StripLeadingSpaces(llvm::StringRef &Str)
69 while (!Str.empty() && isspace(Str[0]))
73 // Equivalent class: {"-", "to", "To", "TO"} of range specifier array.
74 static const char* RSA[4] = { "-", "to", "To", "TO" };
76 // Return the index to RSA if found; otherwise -1 is returned.
78 WithRSAIndex(llvm::StringRef &Arg)
82 for (i = 0; i < 4; ++i)
83 if (Arg.find(RSA[i]) != llvm::StringRef::npos)
88 // Return true if wp_ids is successfully populated with the watch ids.
91 CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(Target *target, Args &args, std::vector<uint32_t> &wp_ids)
93 // Pre-condition: args.GetArgumentCount() > 0.
94 if (args.GetArgumentCount() == 0)
98 WatchpointSP watch_sp = target->GetLastCreatedWatchpoint();
101 wp_ids.push_back(watch_sp->GetID());
108 llvm::StringRef Minus("-");
109 std::vector<llvm::StringRef> StrRefArgs;
110 std::pair<llvm::StringRef, llvm::StringRef> Pair;
113 // Go through the argments and make a canonical form of arg list containing
114 // only numbers with possible "-" in between.
115 for (i = 0; i < args.GetArgumentCount(); ++i) {
116 llvm::StringRef Arg(args.GetArgumentAtIndex(i));
117 if ((idx = WithRSAIndex(Arg)) == -1) {
118 StrRefArgs.push_back(Arg);
121 // The Arg contains the range specifier, split it, then.
122 Pair = Arg.split(RSA[idx]);
123 if (!Pair.first.empty())
124 StrRefArgs.push_back(Pair.first);
125 StrRefArgs.push_back(Minus);
126 if (!Pair.second.empty())
127 StrRefArgs.push_back(Pair.second);
129 // Now process the canonical list and fill in the vector of uint32_t's.
130 // If there is any error, return false and the client should ignore wp_ids.
131 uint32_t beg, end, id;
132 size_t size = StrRefArgs.size();
133 bool in_range = false;
134 for (i = 0; i < size; ++i) {
135 llvm::StringRef Arg = StrRefArgs[i];
137 // Look for the 'end' of the range. Note StringRef::getAsInteger()
138 // returns true to signify error while parsing.
139 if (Arg.getAsInteger(0, end))
141 // Found a range! Now append the elements.
142 for (id = beg; id <= end; ++id)
143 wp_ids.push_back(id);
147 if (i < (size - 1) && StrRefArgs[i+1] == Minus) {
148 if (Arg.getAsInteger(0, beg))
150 // Turn on the in_range flag, we are looking for end of range next.
151 ++i; in_range = true;
154 // Otherwise, we have a simple ID. Just append it.
155 if (Arg.getAsInteger(0, beg))
157 wp_ids.push_back(beg);
159 // It is an error if after the loop, we're still in_range.
163 return true; // Success!
166 //-------------------------------------------------------------------------
167 // CommandObjectWatchpointList
168 //-------------------------------------------------------------------------
171 class CommandObjectWatchpointList : public CommandObjectParsed
174 CommandObjectWatchpointList (CommandInterpreter &interpreter) :
175 CommandObjectParsed (interpreter,
177 "List all watchpoints at configurable levels of detail.",
179 m_options(interpreter)
181 CommandArgumentEntry arg;
182 CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange);
183 // Add the entry for the first argument for this command to the object's arguments vector.
184 m_arguments.push_back(arg);
188 ~CommandObjectWatchpointList () {}
196 class CommandOptions : public Options
200 CommandOptions (CommandInterpreter &interpreter) :
201 Options(interpreter),
202 m_level(lldb::eDescriptionLevelBrief) // Watchpoint List defaults to brief descriptions
207 ~CommandOptions () {}
210 SetOptionValue (uint32_t option_idx, const char *option_arg)
213 const int short_option = m_getopt_table[option_idx].val;
215 switch (short_option)
218 m_level = lldb::eDescriptionLevelBrief;
221 m_level = lldb::eDescriptionLevelFull;
224 m_level = lldb::eDescriptionLevelVerbose;
227 error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
235 OptionParsingStarting ()
237 m_level = lldb::eDescriptionLevelFull;
240 const OptionDefinition *
243 return g_option_table;
247 // Options table: Required for subclasses of Options.
249 static OptionDefinition g_option_table[];
251 // Instance variables to hold the values for command options.
253 lldb::DescriptionLevel m_level;
258 DoExecute (Args& command, CommandReturnObject &result)
260 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
263 result.AppendError ("Invalid target. No current target or watchpoints.");
264 result.SetStatus (eReturnStatusSuccessFinishNoResult);
268 if (target->GetProcessSP() && target->GetProcessSP()->IsAlive())
270 uint32_t num_supported_hardware_watchpoints;
271 Error error = target->GetProcessSP()->GetWatchpointSupportInfo(num_supported_hardware_watchpoints);
273 result.AppendMessageWithFormat("Number of supported hardware watchpoints: %u\n",
274 num_supported_hardware_watchpoints);
277 const WatchpointList &watchpoints = target->GetWatchpointList();
278 Mutex::Locker locker;
279 target->GetWatchpointList().GetListMutex(locker);
281 size_t num_watchpoints = watchpoints.GetSize();
283 if (num_watchpoints == 0)
285 result.AppendMessage("No watchpoints currently set.");
286 result.SetStatus(eReturnStatusSuccessFinishNoResult);
290 Stream &output_stream = result.GetOutputStream();
292 if (command.GetArgumentCount() == 0)
294 // No watchpoint selected; show info about all currently set watchpoints.
295 result.AppendMessage ("Current watchpoints:");
296 for (size_t i = 0; i < num_watchpoints; ++i)
298 Watchpoint *wp = watchpoints.GetByIndex(i).get();
299 AddWatchpointDescription(&output_stream, wp, m_options.m_level);
301 result.SetStatus(eReturnStatusSuccessFinishNoResult);
305 // Particular watchpoints selected; enable them.
306 std::vector<uint32_t> wp_ids;
307 if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, wp_ids))
309 result.AppendError("Invalid watchpoints specification.");
310 result.SetStatus(eReturnStatusFailed);
314 const size_t size = wp_ids.size();
315 for (size_t i = 0; i < size; ++i)
317 Watchpoint *wp = watchpoints.FindByID(wp_ids[i]).get();
319 AddWatchpointDescription(&output_stream, wp, m_options.m_level);
320 result.SetStatus(eReturnStatusSuccessFinishNoResult);
324 return result.Succeeded();
328 CommandOptions m_options;
331 //-------------------------------------------------------------------------
332 // CommandObjectWatchpointList::Options
333 //-------------------------------------------------------------------------
334 #pragma mark List::CommandOptions
336 CommandObjectWatchpointList::CommandOptions::g_option_table[] =
338 { LLDB_OPT_SET_1, false, "brief", 'b', no_argument, NULL, 0, eArgTypeNone,
339 "Give a brief description of the watchpoint (no location info)."},
341 { LLDB_OPT_SET_2, false, "full", 'f', no_argument, NULL, 0, eArgTypeNone,
342 "Give a full description of the watchpoint and its locations."},
344 { LLDB_OPT_SET_3, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone,
345 "Explain everything we know about the watchpoint (for debugging debugger bugs)." },
347 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
350 //-------------------------------------------------------------------------
351 // CommandObjectWatchpointEnable
352 //-------------------------------------------------------------------------
355 class CommandObjectWatchpointEnable : public CommandObjectParsed
358 CommandObjectWatchpointEnable (CommandInterpreter &interpreter) :
359 CommandObjectParsed (interpreter,
361 "Enable the specified disabled watchpoint(s). If no watchpoints are specified, enable all of them.",
364 CommandArgumentEntry arg;
365 CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange);
366 // Add the entry for the first argument for this command to the object's arguments vector.
367 m_arguments.push_back(arg);
371 ~CommandObjectWatchpointEnable () {}
375 DoExecute (Args& command,
376 CommandReturnObject &result)
378 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
379 if (!CheckTargetForWatchpointOperations(target, result))
382 Mutex::Locker locker;
383 target->GetWatchpointList().GetListMutex(locker);
385 const WatchpointList &watchpoints = target->GetWatchpointList();
387 size_t num_watchpoints = watchpoints.GetSize();
389 if (num_watchpoints == 0)
391 result.AppendError("No watchpoints exist to be enabled.");
392 result.SetStatus(eReturnStatusFailed);
396 if (command.GetArgumentCount() == 0)
398 // No watchpoint selected; enable all currently set watchpoints.
399 target->EnableAllWatchpoints();
400 result.AppendMessageWithFormat("All watchpoints enabled. (%lu watchpoints)\n", num_watchpoints);
401 result.SetStatus(eReturnStatusSuccessFinishNoResult);
405 // Particular watchpoints selected; enable them.
406 std::vector<uint32_t> wp_ids;
407 if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, wp_ids))
409 result.AppendError("Invalid watchpoints specification.");
410 result.SetStatus(eReturnStatusFailed);
415 const size_t size = wp_ids.size();
416 for (size_t i = 0; i < size; ++i)
417 if (target->EnableWatchpointByID(wp_ids[i]))
419 result.AppendMessageWithFormat("%d watchpoints enabled.\n", count);
420 result.SetStatus(eReturnStatusSuccessFinishNoResult);
423 return result.Succeeded();
429 //-------------------------------------------------------------------------
430 // CommandObjectWatchpointDisable
431 //-------------------------------------------------------------------------
434 class CommandObjectWatchpointDisable : public CommandObjectParsed
437 CommandObjectWatchpointDisable (CommandInterpreter &interpreter) :
438 CommandObjectParsed (interpreter,
439 "watchpoint disable",
440 "Disable the specified watchpoint(s) without removing it/them. If no watchpoints are specified, disable them all.",
443 CommandArgumentEntry arg;
444 CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange);
445 // Add the entry for the first argument for this command to the object's arguments vector.
446 m_arguments.push_back(arg);
451 ~CommandObjectWatchpointDisable () {}
455 DoExecute (Args& command, CommandReturnObject &result)
457 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
458 if (!CheckTargetForWatchpointOperations(target, result))
461 Mutex::Locker locker;
462 target->GetWatchpointList().GetListMutex(locker);
464 const WatchpointList &watchpoints = target->GetWatchpointList();
465 size_t num_watchpoints = watchpoints.GetSize();
467 if (num_watchpoints == 0)
469 result.AppendError("No watchpoints exist to be disabled.");
470 result.SetStatus(eReturnStatusFailed);
474 if (command.GetArgumentCount() == 0)
476 // No watchpoint selected; disable all currently set watchpoints.
477 if (target->DisableAllWatchpoints())
479 result.AppendMessageWithFormat("All watchpoints disabled. (%lu watchpoints)\n", num_watchpoints);
480 result.SetStatus(eReturnStatusSuccessFinishNoResult);
484 result.AppendError("Disable all watchpoints failed\n");
485 result.SetStatus(eReturnStatusFailed);
490 // Particular watchpoints selected; disable them.
491 std::vector<uint32_t> wp_ids;
492 if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, wp_ids))
494 result.AppendError("Invalid watchpoints specification.");
495 result.SetStatus(eReturnStatusFailed);
500 const size_t size = wp_ids.size();
501 for (size_t i = 0; i < size; ++i)
502 if (target->DisableWatchpointByID(wp_ids[i]))
504 result.AppendMessageWithFormat("%d watchpoints disabled.\n", count);
505 result.SetStatus(eReturnStatusSuccessFinishNoResult);
508 return result.Succeeded();
513 //-------------------------------------------------------------------------
514 // CommandObjectWatchpointDelete
515 //-------------------------------------------------------------------------
518 class CommandObjectWatchpointDelete : public CommandObjectParsed
521 CommandObjectWatchpointDelete (CommandInterpreter &interpreter) :
522 CommandObjectParsed(interpreter,
524 "Delete the specified watchpoint(s). If no watchpoints are specified, delete them all.",
527 CommandArgumentEntry arg;
528 CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange);
529 // Add the entry for the first argument for this command to the object's arguments vector.
530 m_arguments.push_back(arg);
534 ~CommandObjectWatchpointDelete () {}
538 DoExecute (Args& command, CommandReturnObject &result)
540 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
541 if (!CheckTargetForWatchpointOperations(target, result))
544 Mutex::Locker locker;
545 target->GetWatchpointList().GetListMutex(locker);
547 const WatchpointList &watchpoints = target->GetWatchpointList();
549 size_t num_watchpoints = watchpoints.GetSize();
551 if (num_watchpoints == 0)
553 result.AppendError("No watchpoints exist to be deleted.");
554 result.SetStatus(eReturnStatusFailed);
558 if (command.GetArgumentCount() == 0)
560 if (!m_interpreter.Confirm("About to delete all watchpoints, do you want to do that?", true))
562 result.AppendMessage("Operation cancelled...");
566 target->RemoveAllWatchpoints();
567 result.AppendMessageWithFormat("All watchpoints removed. (%lu watchpoints)\n", num_watchpoints);
569 result.SetStatus (eReturnStatusSuccessFinishNoResult);
573 // Particular watchpoints selected; delete them.
574 std::vector<uint32_t> wp_ids;
575 if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, wp_ids))
577 result.AppendError("Invalid watchpoints specification.");
578 result.SetStatus(eReturnStatusFailed);
583 const size_t size = wp_ids.size();
584 for (size_t i = 0; i < size; ++i)
585 if (target->RemoveWatchpointByID(wp_ids[i]))
587 result.AppendMessageWithFormat("%d watchpoints deleted.\n",count);
588 result.SetStatus (eReturnStatusSuccessFinishNoResult);
591 return result.Succeeded();
596 //-------------------------------------------------------------------------
597 // CommandObjectWatchpointIgnore
598 //-------------------------------------------------------------------------
600 class CommandObjectWatchpointIgnore : public CommandObjectParsed
603 CommandObjectWatchpointIgnore (CommandInterpreter &interpreter) :
604 CommandObjectParsed (interpreter,
606 "Set ignore count on the specified watchpoint(s). If no watchpoints are specified, set them all.",
608 m_options (interpreter)
610 CommandArgumentEntry arg;
611 CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange);
612 // Add the entry for the first argument for this command to the object's arguments vector.
613 m_arguments.push_back(arg);
617 ~CommandObjectWatchpointIgnore () {}
625 class CommandOptions : public Options
629 CommandOptions (CommandInterpreter &interpreter) :
630 Options (interpreter),
636 ~CommandOptions () {}
639 SetOptionValue (uint32_t option_idx, const char *option_arg)
642 const int short_option = m_getopt_table[option_idx].val;
644 switch (short_option)
648 m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
649 if (m_ignore_count == UINT32_MAX)
650 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
654 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
662 OptionParsingStarting ()
667 const OptionDefinition *
670 return g_option_table;
674 // Options table: Required for subclasses of Options.
676 static OptionDefinition g_option_table[];
678 // Instance variables to hold the values for command options.
680 uint32_t m_ignore_count;
685 DoExecute (Args& command,
686 CommandReturnObject &result)
688 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
689 if (!CheckTargetForWatchpointOperations(target, result))
692 Mutex::Locker locker;
693 target->GetWatchpointList().GetListMutex(locker);
695 const WatchpointList &watchpoints = target->GetWatchpointList();
697 size_t num_watchpoints = watchpoints.GetSize();
699 if (num_watchpoints == 0)
701 result.AppendError("No watchpoints exist to be ignored.");
702 result.SetStatus(eReturnStatusFailed);
706 if (command.GetArgumentCount() == 0)
708 target->IgnoreAllWatchpoints(m_options.m_ignore_count);
709 result.AppendMessageWithFormat("All watchpoints ignored. (%lu watchpoints)\n", num_watchpoints);
710 result.SetStatus (eReturnStatusSuccessFinishNoResult);
714 // Particular watchpoints selected; ignore them.
715 std::vector<uint32_t> wp_ids;
716 if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, wp_ids))
718 result.AppendError("Invalid watchpoints specification.");
719 result.SetStatus(eReturnStatusFailed);
724 const size_t size = wp_ids.size();
725 for (size_t i = 0; i < size; ++i)
726 if (target->IgnoreWatchpointByID(wp_ids[i], m_options.m_ignore_count))
728 result.AppendMessageWithFormat("%d watchpoints ignored.\n",count);
729 result.SetStatus (eReturnStatusSuccessFinishNoResult);
732 return result.Succeeded();
736 CommandOptions m_options;
739 #pragma mark Ignore::CommandOptions
741 CommandObjectWatchpointIgnore::CommandOptions::g_option_table[] =
743 { LLDB_OPT_SET_ALL, true, "ignore-count", 'i', required_argument, NULL, 0, eArgTypeCount, "Set the number of times this watchpoint is skipped before stopping." },
744 { 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL }
748 //-------------------------------------------------------------------------
749 // CommandObjectWatchpointModify
750 //-------------------------------------------------------------------------
753 class CommandObjectWatchpointModify : public CommandObjectParsed
757 CommandObjectWatchpointModify (CommandInterpreter &interpreter) :
758 CommandObjectParsed (interpreter,
760 "Modify the options on a watchpoint or set of watchpoints in the executable. "
761 "If no watchpoint is specified, act on the last created watchpoint. "
762 "Passing an empty argument clears the modification.",
764 m_options (interpreter)
766 CommandArgumentEntry arg;
767 CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange);
768 // Add the entry for the first argument for this command to the object's arguments vector.
769 m_arguments.push_back (arg);
773 ~CommandObjectWatchpointModify () {}
781 class CommandOptions : public Options
785 CommandOptions (CommandInterpreter &interpreter) :
786 Options (interpreter),
788 m_condition_passed (false)
793 ~CommandOptions () {}
796 SetOptionValue (uint32_t option_idx, const char *option_arg)
799 const int short_option = m_getopt_table[option_idx].val;
801 switch (short_option)
804 if (option_arg != NULL)
805 m_condition.assign (option_arg);
808 m_condition_passed = true;
811 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
819 OptionParsingStarting ()
822 m_condition_passed = false;
825 const OptionDefinition*
828 return g_option_table;
831 // Options table: Required for subclasses of Options.
833 static OptionDefinition g_option_table[];
835 // Instance variables to hold the values for command options.
837 std::string m_condition;
838 bool m_condition_passed;
843 DoExecute (Args& command, CommandReturnObject &result)
845 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
846 if (!CheckTargetForWatchpointOperations(target, result))
849 Mutex::Locker locker;
850 target->GetWatchpointList().GetListMutex(locker);
852 const WatchpointList &watchpoints = target->GetWatchpointList();
854 size_t num_watchpoints = watchpoints.GetSize();
856 if (num_watchpoints == 0)
858 result.AppendError("No watchpoints exist to be modified.");
859 result.SetStatus(eReturnStatusFailed);
863 if (command.GetArgumentCount() == 0)
865 WatchpointSP wp_sp = target->GetLastCreatedWatchpoint();
866 wp_sp->SetCondition(m_options.m_condition.c_str());
867 result.SetStatus (eReturnStatusSuccessFinishNoResult);
871 // Particular watchpoints selected; set condition on them.
872 std::vector<uint32_t> wp_ids;
873 if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, wp_ids))
875 result.AppendError("Invalid watchpoints specification.");
876 result.SetStatus(eReturnStatusFailed);
881 const size_t size = wp_ids.size();
882 for (size_t i = 0; i < size; ++i)
884 WatchpointSP wp_sp = watchpoints.FindByID(wp_ids[i]);
887 wp_sp->SetCondition(m_options.m_condition.c_str());
891 result.AppendMessageWithFormat("%d watchpoints modified.\n",count);
892 result.SetStatus (eReturnStatusSuccessFinishNoResult);
895 return result.Succeeded();
899 CommandOptions m_options;
902 #pragma mark Modify::CommandOptions
904 CommandObjectWatchpointModify::CommandOptions::g_option_table[] =
906 { LLDB_OPT_SET_ALL, false, "condition", 'c', required_argument, NULL, 0, eArgTypeExpression, "The watchpoint stops only if this condition expression evaluates to true."},
907 { 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL }
910 //-------------------------------------------------------------------------
911 // CommandObjectWatchpointSetVariable
912 //-------------------------------------------------------------------------
913 #pragma mark SetVariable
915 class CommandObjectWatchpointSetVariable : public CommandObjectParsed
919 CommandObjectWatchpointSetVariable (CommandInterpreter &interpreter) :
920 CommandObjectParsed (interpreter,
921 "watchpoint set variable",
922 "Set a watchpoint on a variable. "
923 "Use the '-w' option to specify the type of watchpoint and "
924 "the '-x' option to specify the byte size to watch for. "
925 "If no '-w' option is specified, it defaults to write. "
926 "If no '-x' option is specified, it defaults to the variable's "
928 "Note that there are limited hardware resources for watchpoints. "
929 "If watchpoint setting fails, consider disable/delete existing ones "
930 "to free up resources.",
933 eFlagTryTargetAPILock |
934 eFlagProcessMustBeLaunched |
935 eFlagProcessMustBePaused ),
936 m_option_group (interpreter),
937 m_option_watchpoint ()
942 watchpoint set variable -w read_wriate my_global_var \n\
943 # Watch my_global_var for read/write access, with the region to watch corresponding to the byte size of the data type.\n");
945 CommandArgumentEntry arg;
946 CommandArgumentData var_name_arg;
948 // Define the only variant of this arg.
949 var_name_arg.arg_type = eArgTypeVarName;
950 var_name_arg.arg_repetition = eArgRepeatPlain;
952 // Push the variant into the argument entry.
953 arg.push_back (var_name_arg);
955 // Push the data for the only argument into the m_arguments vector.
956 m_arguments.push_back (arg);
958 // Absorb the '-w' and '-x' options into our option group.
959 m_option_group.Append (&m_option_watchpoint, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
960 m_option_group.Finalize();
964 ~CommandObjectWatchpointSetVariable () {}
969 return &m_option_group;
973 static size_t GetVariableCallback (void *baton,
975 VariableList &variable_list)
977 Target *target = static_cast<Target *>(baton);
980 return target->GetImages().FindGlobalVariables (ConstString(name),
989 DoExecute (Args& command, CommandReturnObject &result)
991 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
992 StackFrame *frame = m_exe_ctx.GetFramePtr();
994 // If no argument is present, issue an error message. There's no way to set a watchpoint.
995 if (command.GetArgumentCount() <= 0)
997 result.GetErrorStream().Printf("error: required argument missing; specify your program variable to watch for\n");
998 result.SetStatus(eReturnStatusFailed);
1002 // If no '-w' is specified, default to '-w write'.
1003 if (!m_option_watchpoint.watch_type_specified)
1005 m_option_watchpoint.watch_type = OptionGroupWatchpoint::eWatchWrite;
1008 // We passed the sanity check for the command.
1009 // Proceed to set the watchpoint now.
1010 lldb::addr_t addr = 0;
1014 ValueObjectSP valobj_sp;
1015 Stream &output_stream = result.GetOutputStream();
1017 // A simple watch variable gesture allows only one argument.
1018 if (command.GetArgumentCount() != 1)
1020 result.GetErrorStream().Printf("error: specify exactly one variable to watch for\n");
1021 result.SetStatus(eReturnStatusFailed);
1025 // Things have checked out ok...
1027 uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember |
1028 StackFrame::eExpressionPathOptionsAllowDirectIVarAccess;
1029 valobj_sp = frame->GetValueForVariableExpressionPath (command.GetArgumentAtIndex(0),
1037 // Not in the frame; let's check the globals.
1039 VariableList variable_list;
1040 ValueObjectList valobj_list;
1042 Error error (Variable::GetValuesForVariableExpressionPath (command.GetArgumentAtIndex(0),
1043 m_exe_ctx.GetBestExecutionContextScope(),
1044 GetVariableCallback,
1049 if (valobj_list.GetSize())
1050 valobj_sp = valobj_list.GetValueObjectAtIndex(0);
1053 ClangASTType clang_type;
1057 AddressType addr_type;
1058 addr = valobj_sp->GetAddressOf(false, &addr_type);
1059 if (addr_type == eAddressTypeLoad)
1061 // We're in business.
1062 // Find out the size of this variable.
1063 size = m_option_watchpoint.watch_size == 0 ? valobj_sp->GetByteSize()
1064 : m_option_watchpoint.watch_size;
1066 clang_type = valobj_sp->GetClangType();
1070 const char *error_cstr = error.AsCString(NULL);
1072 result.GetErrorStream().Printf("error: %s\n", error_cstr);
1074 result.GetErrorStream().Printf ("error: unable to find any variable expression path that matches '%s'\n",
1075 command.GetArgumentAtIndex(0));
1079 // Now it's time to create the watchpoint.
1080 uint32_t watch_type = m_option_watchpoint.watch_type;
1083 Watchpoint *wp = target->CreateWatchpoint(addr, size, &clang_type, watch_type, error).get();
1086 wp->SetWatchSpec(command.GetArgumentAtIndex(0));
1087 wp->SetWatchVariable(true);
1088 if (var_sp && var_sp->GetDeclaration().GetFile())
1091 // True to show fullpath for declaration file.
1092 var_sp->GetDeclaration().DumpStopContext(&ss, true);
1093 wp->SetDeclInfo(ss.GetString());
1095 output_stream.Printf("Watchpoint created: ");
1096 wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull);
1097 output_stream.EOL();
1098 result.SetStatus(eReturnStatusSuccessFinishResult);
1102 result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%" PRIx64 ", size=%lu, variable expression='%s').\n",
1103 addr, size, command.GetArgumentAtIndex(0));
1104 if (error.AsCString(NULL))
1105 result.AppendError(error.AsCString());
1106 result.SetStatus(eReturnStatusFailed);
1109 return result.Succeeded();
1113 OptionGroupOptions m_option_group;
1114 OptionGroupWatchpoint m_option_watchpoint;
1117 //-------------------------------------------------------------------------
1118 // CommandObjectWatchpointSetExpression
1119 //-------------------------------------------------------------------------
1122 class CommandObjectWatchpointSetExpression : public CommandObjectRaw
1126 CommandObjectWatchpointSetExpression (CommandInterpreter &interpreter) :
1127 CommandObjectRaw (interpreter,
1128 "watchpoint set expression",
1129 "Set a watchpoint on an address by supplying an expression. "
1130 "Use the '-w' option to specify the type of watchpoint and "
1131 "the '-x' option to specify the byte size to watch for. "
1132 "If no '-w' option is specified, it defaults to write. "
1133 "If no '-x' option is specified, it defaults to the target's "
1134 "pointer byte size. "
1135 "Note that there are limited hardware resources for watchpoints. "
1136 "If watchpoint setting fails, consider disable/delete existing ones "
1137 "to free up resources.",
1139 eFlagRequiresFrame |
1140 eFlagTryTargetAPILock |
1141 eFlagProcessMustBeLaunched |
1142 eFlagProcessMustBePaused ),
1143 m_option_group (interpreter),
1144 m_option_watchpoint ()
1149 watchpoint set expression -w write -x 1 -- foo + 32\n\
1150 # Watch write access for the 1-byte region pointed to by the address 'foo + 32'.\n");
1152 CommandArgumentEntry arg;
1153 CommandArgumentData expression_arg;
1155 // Define the only variant of this arg.
1156 expression_arg.arg_type = eArgTypeExpression;
1157 expression_arg.arg_repetition = eArgRepeatPlain;
1159 // Push the only variant into the argument entry.
1160 arg.push_back (expression_arg);
1162 // Push the data for the only argument into the m_arguments vector.
1163 m_arguments.push_back (arg);
1165 // Absorb the '-w' and '-x' options into our option group.
1166 m_option_group.Append (&m_option_watchpoint, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
1167 m_option_group.Finalize();
1172 ~CommandObjectWatchpointSetExpression () {}
1174 // Overrides base class's behavior where WantsCompletion = !WantsRawCommandString.
1176 WantsCompletion() { return true; }
1181 return &m_option_group;
1186 DoExecute (const char *raw_command, CommandReturnObject &result)
1188 m_option_group.NotifyOptionParsingStarting(); // This is a raw command, so notify the option group
1190 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1191 StackFrame *frame = m_exe_ctx.GetFramePtr();
1193 Args command(raw_command);
1194 const char *expr = NULL;
1195 if (raw_command[0] == '-')
1197 // We have some options and these options MUST end with --.
1198 const char *end_options = NULL;
1199 const char *s = raw_command;
1202 end_options = ::strstr (s, "--");
1205 end_options += 2; // Get past the "--"
1206 if (::isspace (end_options[0]))
1209 while (::isspace (*expr))
1219 Args args (raw_command, end_options - raw_command);
1220 if (!ParseOptions (args, result))
1223 Error error (m_option_group.NotifyOptionParsingFinished());
1226 result.AppendError (error.AsCString());
1227 result.SetStatus (eReturnStatusFailed);
1236 // If no argument is present, issue an error message. There's no way to set a watchpoint.
1237 if (command.GetArgumentCount() == 0)
1239 result.GetErrorStream().Printf("error: required argument missing; specify an expression to evaulate into the address to watch for\n");
1240 result.SetStatus(eReturnStatusFailed);
1244 // If no '-w' is specified, default to '-w write'.
1245 if (!m_option_watchpoint.watch_type_specified)
1247 m_option_watchpoint.watch_type = OptionGroupWatchpoint::eWatchWrite;
1250 // We passed the sanity check for the command.
1251 // Proceed to set the watchpoint now.
1252 lldb::addr_t addr = 0;
1255 ValueObjectSP valobj_sp;
1257 // Use expression evaluation to arrive at the address to watch.
1258 EvaluateExpressionOptions options;
1259 options.SetCoerceToId(false)
1260 .SetUnwindOnError(true)
1261 .SetKeepInMemory(false)
1265 ExecutionResults expr_result = target->EvaluateExpression (expr,
1269 if (expr_result != eExecutionCompleted)
1271 result.GetErrorStream().Printf("error: expression evaluation of address to watch failed\n");
1272 result.GetErrorStream().Printf("expression evaluated: %s\n", expr);
1273 result.SetStatus(eReturnStatusFailed);
1277 // Get the address to watch.
1278 bool success = false;
1279 addr = valobj_sp->GetValueAsUnsigned(0, &success);
1282 result.GetErrorStream().Printf("error: expression did not evaluate to an address\n");
1283 result.SetStatus(eReturnStatusFailed);
1287 if (m_option_watchpoint.watch_size != 0)
1288 size = m_option_watchpoint.watch_size;
1290 size = target->GetArchitecture().GetAddressByteSize();
1292 // Now it's time to create the watchpoint.
1293 uint32_t watch_type = m_option_watchpoint.watch_type;
1295 // Fetch the type from the value object, the type of the watched object is the pointee type
1296 /// of the expression, so convert to that if we found a valid type.
1297 ClangASTType clang_type(valobj_sp->GetClangType());
1300 Watchpoint *wp = target->CreateWatchpoint(addr, size, &clang_type, watch_type, error).get();
1303 Stream &output_stream = result.GetOutputStream();
1304 output_stream.Printf("Watchpoint created: ");
1305 wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull);
1306 output_stream.EOL();
1307 result.SetStatus(eReturnStatusSuccessFinishResult);
1311 result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%" PRIx64 ", size=%lu).\n",
1313 if (error.AsCString(NULL))
1314 result.AppendError(error.AsCString());
1315 result.SetStatus(eReturnStatusFailed);
1318 return result.Succeeded();
1322 OptionGroupOptions m_option_group;
1323 OptionGroupWatchpoint m_option_watchpoint;
1326 //-------------------------------------------------------------------------
1327 // CommandObjectWatchpointSet
1328 //-------------------------------------------------------------------------
1331 class CommandObjectWatchpointSet : public CommandObjectMultiword
1335 CommandObjectWatchpointSet (CommandInterpreter &interpreter) :
1336 CommandObjectMultiword (interpreter,
1338 "A set of commands for setting a watchpoint.",
1339 "watchpoint set <subcommand> [<subcommand-options>]")
1342 LoadSubCommand ("variable", CommandObjectSP (new CommandObjectWatchpointSetVariable (interpreter)));
1343 LoadSubCommand ("expression", CommandObjectSP (new CommandObjectWatchpointSetExpression (interpreter)));
1348 ~CommandObjectWatchpointSet () {}
1352 //-------------------------------------------------------------------------
1353 // CommandObjectMultiwordWatchpoint
1354 //-------------------------------------------------------------------------
1355 #pragma mark MultiwordWatchpoint
1357 CommandObjectMultiwordWatchpoint::CommandObjectMultiwordWatchpoint(CommandInterpreter &interpreter) :
1358 CommandObjectMultiword (interpreter,
1360 "A set of commands for operating on watchpoints.",
1361 "watchpoint <command> [<command-options>]")
1363 CommandObjectSP list_command_object (new CommandObjectWatchpointList (interpreter));
1364 CommandObjectSP enable_command_object (new CommandObjectWatchpointEnable (interpreter));
1365 CommandObjectSP disable_command_object (new CommandObjectWatchpointDisable (interpreter));
1366 CommandObjectSP delete_command_object (new CommandObjectWatchpointDelete (interpreter));
1367 CommandObjectSP ignore_command_object (new CommandObjectWatchpointIgnore (interpreter));
1368 CommandObjectSP command_command_object (new CommandObjectWatchpointCommand (interpreter));
1369 CommandObjectSP modify_command_object (new CommandObjectWatchpointModify (interpreter));
1370 CommandObjectSP set_command_object (new CommandObjectWatchpointSet (interpreter));
1372 list_command_object->SetCommandName ("watchpoint list");
1373 enable_command_object->SetCommandName("watchpoint enable");
1374 disable_command_object->SetCommandName("watchpoint disable");
1375 delete_command_object->SetCommandName("watchpoint delete");
1376 ignore_command_object->SetCommandName("watchpoint ignore");
1377 command_command_object->SetCommandName ("watchpoint command");
1378 modify_command_object->SetCommandName("watchpoint modify");
1379 set_command_object->SetCommandName("watchpoint set");
1381 LoadSubCommand ("list", list_command_object);
1382 LoadSubCommand ("enable", enable_command_object);
1383 LoadSubCommand ("disable", disable_command_object);
1384 LoadSubCommand ("delete", delete_command_object);
1385 LoadSubCommand ("ignore", ignore_command_object);
1386 LoadSubCommand ("command", command_command_object);
1387 LoadSubCommand ("modify", modify_command_object);
1388 LoadSubCommand ("set", set_command_object);
1391 CommandObjectMultiwordWatchpoint::~CommandObjectMultiwordWatchpoint()