1 //===-- CommandObjectWatchpoint.cpp -----------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/lldb-python.h"
11
12 #include "CommandObjectWatchpoint.h"
13 #include "CommandObjectWatchpointCommand.h"
14
15 // C Includes
16 // C++ Includes
17 // Other libraries and framework includes
18 // Project 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"
30
31 #include <vector>
32
33 using namespace lldb;
34 using namespace lldb_private;
35
36 static void
AddWatchpointDescription(Stream * s,Watchpoint * wp,lldb::DescriptionLevel level)37 AddWatchpointDescription(Stream *s, Watchpoint *wp, lldb::DescriptionLevel level)
38 {
39 s->IndentMore();
40 wp->GetDescription(s, level);
41 s->IndentLess();
42 s->EOL();
43 }
44
45 static bool
CheckTargetForWatchpointOperations(Target * target,CommandReturnObject & result)46 CheckTargetForWatchpointOperations(Target *target, CommandReturnObject &result)
47 {
48 if (target == NULL)
49 {
50 result.AppendError ("Invalid target. No existing target or watchpoints.");
51 result.SetStatus (eReturnStatusFailed);
52 return false;
53 }
54 bool process_is_valid = target->GetProcessSP() && target->GetProcessSP()->IsAlive();
55 if (!process_is_valid)
56 {
57 result.AppendError ("Thre's no process or it is not alive.");
58 result.SetStatus (eReturnStatusFailed);
59 return false;
60 }
61 // Target passes our checks, return true.
62 return true;
63 }
64
65 // FIXME: This doesn't seem to be the right place for this functionality.
66 #include "llvm/ADT/StringRef.h"
StripLeadingSpaces(llvm::StringRef & Str)67 static inline void StripLeadingSpaces(llvm::StringRef &Str)
68 {
69 while (!Str.empty() && isspace(Str[0]))
70 Str = Str.substr(1);
71 }
72
73 // Equivalent class: {"-", "to", "To", "TO"} of range specifier array.
74 static const char* RSA[4] = { "-", "to", "To", "TO" };
75
76 // Return the index to RSA if found; otherwise -1 is returned.
77 static int32_t
WithRSAIndex(llvm::StringRef & Arg)78 WithRSAIndex(llvm::StringRef &Arg)
79 {
80
81 uint32_t i;
82 for (i = 0; i < 4; ++i)
83 if (Arg.find(RSA[i]) != llvm::StringRef::npos)
84 return i;
85 return -1;
86 }
87
88 // Return true if wp_ids is successfully populated with the watch ids.
89 // False otherwise.
90 bool
VerifyWatchpointIDs(Target * target,Args & args,std::vector<uint32_t> & wp_ids)91 CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(Target *target, Args &args, std::vector<uint32_t> &wp_ids)
92 {
93 // Pre-condition: args.GetArgumentCount() > 0.
94 if (args.GetArgumentCount() == 0)
95 {
96 if (target == NULL)
97 return false;
98 WatchpointSP watch_sp = target->GetLastCreatedWatchpoint();
99 if (watch_sp)
100 {
101 wp_ids.push_back(watch_sp->GetID());
102 return true;
103 }
104 else
105 return false;
106 }
107
108 llvm::StringRef Minus("-");
109 std::vector<llvm::StringRef> StrRefArgs;
110 std::pair<llvm::StringRef, llvm::StringRef> Pair;
111 size_t i;
112 int32_t idx;
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);
119 continue;
120 }
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);
128 }
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];
136 if (in_range) {
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))
140 return false;
141 // Found a range! Now append the elements.
142 for (id = beg; id <= end; ++id)
143 wp_ids.push_back(id);
144 in_range = false;
145 continue;
146 }
147 if (i < (size - 1) && StrRefArgs[i+1] == Minus) {
148 if (Arg.getAsInteger(0, beg))
149 return false;
150 // Turn on the in_range flag, we are looking for end of range next.
151 ++i; in_range = true;
152 continue;
153 }
154 // Otherwise, we have a simple ID. Just append it.
155 if (Arg.getAsInteger(0, beg))
156 return false;
157 wp_ids.push_back(beg);
158 }
159 // It is an error if after the loop, we're still in_range.
160 if (in_range)
161 return false;
162
163 return true; // Success!
164 }
165
166 //-------------------------------------------------------------------------
167 // CommandObjectWatchpointList
168 //-------------------------------------------------------------------------
169 #pragma mark List
170
171 class CommandObjectWatchpointList : public CommandObjectParsed
172 {
173 public:
CommandObjectWatchpointList(CommandInterpreter & interpreter)174 CommandObjectWatchpointList (CommandInterpreter &interpreter) :
175 CommandObjectParsed (interpreter,
176 "watchpoint list",
177 "List all watchpoints at configurable levels of detail.",
178 NULL),
179 m_options(interpreter)
180 {
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);
185 }
186
187 virtual
~CommandObjectWatchpointList()188 ~CommandObjectWatchpointList () {}
189
190 virtual Options *
GetOptions()191 GetOptions ()
192 {
193 return &m_options;
194 }
195
196 class CommandOptions : public Options
197 {
198 public:
199
CommandOptions(CommandInterpreter & interpreter)200 CommandOptions (CommandInterpreter &interpreter) :
201 Options(interpreter),
202 m_level(lldb::eDescriptionLevelBrief) // Watchpoint List defaults to brief descriptions
203 {
204 }
205
206 virtual
~CommandOptions()207 ~CommandOptions () {}
208
209 virtual Error
SetOptionValue(uint32_t option_idx,const char * option_arg)210 SetOptionValue (uint32_t option_idx, const char *option_arg)
211 {
212 Error error;
213 const int short_option = m_getopt_table[option_idx].val;
214
215 switch (short_option)
216 {
217 case 'b':
218 m_level = lldb::eDescriptionLevelBrief;
219 break;
220 case 'f':
221 m_level = lldb::eDescriptionLevelFull;
222 break;
223 case 'v':
224 m_level = lldb::eDescriptionLevelVerbose;
225 break;
226 default:
227 error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
228 break;
229 }
230
231 return error;
232 }
233
234 void
OptionParsingStarting()235 OptionParsingStarting ()
236 {
237 m_level = lldb::eDescriptionLevelFull;
238 }
239
240 const OptionDefinition *
GetDefinitions()241 GetDefinitions ()
242 {
243 return g_option_table;
244 }
245
246
247 // Options table: Required for subclasses of Options.
248
249 static OptionDefinition g_option_table[];
250
251 // Instance variables to hold the values for command options.
252
253 lldb::DescriptionLevel m_level;
254 };
255
256 protected:
257 virtual bool
DoExecute(Args & command,CommandReturnObject & result)258 DoExecute (Args& command, CommandReturnObject &result)
259 {
260 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
261 if (target == NULL)
262 {
263 result.AppendError ("Invalid target. No current target or watchpoints.");
264 result.SetStatus (eReturnStatusSuccessFinishNoResult);
265 return true;
266 }
267
268 if (target->GetProcessSP() && target->GetProcessSP()->IsAlive())
269 {
270 uint32_t num_supported_hardware_watchpoints;
271 Error error = target->GetProcessSP()->GetWatchpointSupportInfo(num_supported_hardware_watchpoints);
272 if (error.Success())
273 result.AppendMessageWithFormat("Number of supported hardware watchpoints: %u\n",
274 num_supported_hardware_watchpoints);
275 }
276
277 const WatchpointList &watchpoints = target->GetWatchpointList();
278 Mutex::Locker locker;
279 target->GetWatchpointList().GetListMutex(locker);
280
281 size_t num_watchpoints = watchpoints.GetSize();
282
283 if (num_watchpoints == 0)
284 {
285 result.AppendMessage("No watchpoints currently set.");
286 result.SetStatus(eReturnStatusSuccessFinishNoResult);
287 return true;
288 }
289
290 Stream &output_stream = result.GetOutputStream();
291
292 if (command.GetArgumentCount() == 0)
293 {
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)
297 {
298 Watchpoint *wp = watchpoints.GetByIndex(i).get();
299 AddWatchpointDescription(&output_stream, wp, m_options.m_level);
300 }
301 result.SetStatus(eReturnStatusSuccessFinishNoResult);
302 }
303 else
304 {
305 // Particular watchpoints selected; enable them.
306 std::vector<uint32_t> wp_ids;
307 if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, wp_ids))
308 {
309 result.AppendError("Invalid watchpoints specification.");
310 result.SetStatus(eReturnStatusFailed);
311 return false;
312 }
313
314 const size_t size = wp_ids.size();
315 for (size_t i = 0; i < size; ++i)
316 {
317 Watchpoint *wp = watchpoints.FindByID(wp_ids[i]).get();
318 if (wp)
319 AddWatchpointDescription(&output_stream, wp, m_options.m_level);
320 result.SetStatus(eReturnStatusSuccessFinishNoResult);
321 }
322 }
323
324 return result.Succeeded();
325 }
326
327 private:
328 CommandOptions m_options;
329 };
330
331 //-------------------------------------------------------------------------
332 // CommandObjectWatchpointList::Options
333 //-------------------------------------------------------------------------
334 #pragma mark List::CommandOptions
335 OptionDefinition
336 CommandObjectWatchpointList::CommandOptions::g_option_table[] =
337 {
338 { LLDB_OPT_SET_1, false, "brief", 'b', no_argument, NULL, 0, eArgTypeNone,
339 "Give a brief description of the watchpoint (no location info)."},
340
341 { LLDB_OPT_SET_2, false, "full", 'f', no_argument, NULL, 0, eArgTypeNone,
342 "Give a full description of the watchpoint and its locations."},
343
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)." },
346
347 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
348 };
349
350 //-------------------------------------------------------------------------
351 // CommandObjectWatchpointEnable
352 //-------------------------------------------------------------------------
353 #pragma mark Enable
354
355 class CommandObjectWatchpointEnable : public CommandObjectParsed
356 {
357 public:
CommandObjectWatchpointEnable(CommandInterpreter & interpreter)358 CommandObjectWatchpointEnable (CommandInterpreter &interpreter) :
359 CommandObjectParsed (interpreter,
360 "enable",
361 "Enable the specified disabled watchpoint(s). If no watchpoints are specified, enable all of them.",
362 NULL)
363 {
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);
368 }
369
370 virtual
~CommandObjectWatchpointEnable()371 ~CommandObjectWatchpointEnable () {}
372
373 protected:
374 virtual bool
DoExecute(Args & command,CommandReturnObject & result)375 DoExecute (Args& command,
376 CommandReturnObject &result)
377 {
378 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
379 if (!CheckTargetForWatchpointOperations(target, result))
380 return false;
381
382 Mutex::Locker locker;
383 target->GetWatchpointList().GetListMutex(locker);
384
385 const WatchpointList &watchpoints = target->GetWatchpointList();
386
387 size_t num_watchpoints = watchpoints.GetSize();
388
389 if (num_watchpoints == 0)
390 {
391 result.AppendError("No watchpoints exist to be enabled.");
392 result.SetStatus(eReturnStatusFailed);
393 return false;
394 }
395
396 if (command.GetArgumentCount() == 0)
397 {
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);
402 }
403 else
404 {
405 // Particular watchpoints selected; enable them.
406 std::vector<uint32_t> wp_ids;
407 if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, wp_ids))
408 {
409 result.AppendError("Invalid watchpoints specification.");
410 result.SetStatus(eReturnStatusFailed);
411 return false;
412 }
413
414 int count = 0;
415 const size_t size = wp_ids.size();
416 for (size_t i = 0; i < size; ++i)
417 if (target->EnableWatchpointByID(wp_ids[i]))
418 ++count;
419 result.AppendMessageWithFormat("%d watchpoints enabled.\n", count);
420 result.SetStatus(eReturnStatusSuccessFinishNoResult);
421 }
422
423 return result.Succeeded();
424 }
425
426 private:
427 };
428
429 //-------------------------------------------------------------------------
430 // CommandObjectWatchpointDisable
431 //-------------------------------------------------------------------------
432 #pragma mark Disable
433
434 class CommandObjectWatchpointDisable : public CommandObjectParsed
435 {
436 public:
CommandObjectWatchpointDisable(CommandInterpreter & interpreter)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.",
441 NULL)
442 {
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);
447 }
448
449
450 virtual
~CommandObjectWatchpointDisable()451 ~CommandObjectWatchpointDisable () {}
452
453 protected:
454 virtual bool
DoExecute(Args & command,CommandReturnObject & result)455 DoExecute (Args& command, CommandReturnObject &result)
456 {
457 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
458 if (!CheckTargetForWatchpointOperations(target, result))
459 return false;
460
461 Mutex::Locker locker;
462 target->GetWatchpointList().GetListMutex(locker);
463
464 const WatchpointList &watchpoints = target->GetWatchpointList();
465 size_t num_watchpoints = watchpoints.GetSize();
466
467 if (num_watchpoints == 0)
468 {
469 result.AppendError("No watchpoints exist to be disabled.");
470 result.SetStatus(eReturnStatusFailed);
471 return false;
472 }
473
474 if (command.GetArgumentCount() == 0)
475 {
476 // No watchpoint selected; disable all currently set watchpoints.
477 if (target->DisableAllWatchpoints())
478 {
479 result.AppendMessageWithFormat("All watchpoints disabled. (%lu watchpoints)\n", num_watchpoints);
480 result.SetStatus(eReturnStatusSuccessFinishNoResult);
481 }
482 else
483 {
484 result.AppendError("Disable all watchpoints failed\n");
485 result.SetStatus(eReturnStatusFailed);
486 }
487 }
488 else
489 {
490 // Particular watchpoints selected; disable them.
491 std::vector<uint32_t> wp_ids;
492 if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, wp_ids))
493 {
494 result.AppendError("Invalid watchpoints specification.");
495 result.SetStatus(eReturnStatusFailed);
496 return false;
497 }
498
499 int count = 0;
500 const size_t size = wp_ids.size();
501 for (size_t i = 0; i < size; ++i)
502 if (target->DisableWatchpointByID(wp_ids[i]))
503 ++count;
504 result.AppendMessageWithFormat("%d watchpoints disabled.\n", count);
505 result.SetStatus(eReturnStatusSuccessFinishNoResult);
506 }
507
508 return result.Succeeded();
509 }
510
511 };
512
513 //-------------------------------------------------------------------------
514 // CommandObjectWatchpointDelete
515 //-------------------------------------------------------------------------
516 #pragma mark Delete
517
518 class CommandObjectWatchpointDelete : public CommandObjectParsed
519 {
520 public:
CommandObjectWatchpointDelete(CommandInterpreter & interpreter)521 CommandObjectWatchpointDelete (CommandInterpreter &interpreter) :
522 CommandObjectParsed(interpreter,
523 "watchpoint delete",
524 "Delete the specified watchpoint(s). If no watchpoints are specified, delete them all.",
525 NULL)
526 {
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);
531 }
532
533 virtual
~CommandObjectWatchpointDelete()534 ~CommandObjectWatchpointDelete () {}
535
536 protected:
537 virtual bool
DoExecute(Args & command,CommandReturnObject & result)538 DoExecute (Args& command, CommandReturnObject &result)
539 {
540 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
541 if (!CheckTargetForWatchpointOperations(target, result))
542 return false;
543
544 Mutex::Locker locker;
545 target->GetWatchpointList().GetListMutex(locker);
546
547 const WatchpointList &watchpoints = target->GetWatchpointList();
548
549 size_t num_watchpoints = watchpoints.GetSize();
550
551 if (num_watchpoints == 0)
552 {
553 result.AppendError("No watchpoints exist to be deleted.");
554 result.SetStatus(eReturnStatusFailed);
555 return false;
556 }
557
558 if (command.GetArgumentCount() == 0)
559 {
560 if (!m_interpreter.Confirm("About to delete all watchpoints, do you want to do that?", true))
561 {
562 result.AppendMessage("Operation cancelled...");
563 }
564 else
565 {
566 target->RemoveAllWatchpoints();
567 result.AppendMessageWithFormat("All watchpoints removed. (%lu watchpoints)\n", num_watchpoints);
568 }
569 result.SetStatus (eReturnStatusSuccessFinishNoResult);
570 }
571 else
572 {
573 // Particular watchpoints selected; delete them.
574 std::vector<uint32_t> wp_ids;
575 if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, wp_ids))
576 {
577 result.AppendError("Invalid watchpoints specification.");
578 result.SetStatus(eReturnStatusFailed);
579 return false;
580 }
581
582 int count = 0;
583 const size_t size = wp_ids.size();
584 for (size_t i = 0; i < size; ++i)
585 if (target->RemoveWatchpointByID(wp_ids[i]))
586 ++count;
587 result.AppendMessageWithFormat("%d watchpoints deleted.\n",count);
588 result.SetStatus (eReturnStatusSuccessFinishNoResult);
589 }
590
591 return result.Succeeded();
592 }
593
594 };
595
596 //-------------------------------------------------------------------------
597 // CommandObjectWatchpointIgnore
598 //-------------------------------------------------------------------------
599
600 class CommandObjectWatchpointIgnore : public CommandObjectParsed
601 {
602 public:
CommandObjectWatchpointIgnore(CommandInterpreter & interpreter)603 CommandObjectWatchpointIgnore (CommandInterpreter &interpreter) :
604 CommandObjectParsed (interpreter,
605 "watchpoint ignore",
606 "Set ignore count on the specified watchpoint(s). If no watchpoints are specified, set them all.",
607 NULL),
608 m_options (interpreter)
609 {
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);
614 }
615
616 virtual
~CommandObjectWatchpointIgnore()617 ~CommandObjectWatchpointIgnore () {}
618
619 virtual Options *
GetOptions()620 GetOptions ()
621 {
622 return &m_options;
623 }
624
625 class CommandOptions : public Options
626 {
627 public:
628
CommandOptions(CommandInterpreter & interpreter)629 CommandOptions (CommandInterpreter &interpreter) :
630 Options (interpreter),
631 m_ignore_count (0)
632 {
633 }
634
635 virtual
~CommandOptions()636 ~CommandOptions () {}
637
638 virtual Error
SetOptionValue(uint32_t option_idx,const char * option_arg)639 SetOptionValue (uint32_t option_idx, const char *option_arg)
640 {
641 Error error;
642 const int short_option = m_getopt_table[option_idx].val;
643
644 switch (short_option)
645 {
646 case 'i':
647 {
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);
651 }
652 break;
653 default:
654 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
655 break;
656 }
657
658 return error;
659 }
660
661 void
OptionParsingStarting()662 OptionParsingStarting ()
663 {
664 m_ignore_count = 0;
665 }
666
667 const OptionDefinition *
GetDefinitions()668 GetDefinitions ()
669 {
670 return g_option_table;
671 }
672
673
674 // Options table: Required for subclasses of Options.
675
676 static OptionDefinition g_option_table[];
677
678 // Instance variables to hold the values for command options.
679
680 uint32_t m_ignore_count;
681 };
682
683 protected:
684 virtual bool
DoExecute(Args & command,CommandReturnObject & result)685 DoExecute (Args& command,
686 CommandReturnObject &result)
687 {
688 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
689 if (!CheckTargetForWatchpointOperations(target, result))
690 return false;
691
692 Mutex::Locker locker;
693 target->GetWatchpointList().GetListMutex(locker);
694
695 const WatchpointList &watchpoints = target->GetWatchpointList();
696
697 size_t num_watchpoints = watchpoints.GetSize();
698
699 if (num_watchpoints == 0)
700 {
701 result.AppendError("No watchpoints exist to be ignored.");
702 result.SetStatus(eReturnStatusFailed);
703 return false;
704 }
705
706 if (command.GetArgumentCount() == 0)
707 {
708 target->IgnoreAllWatchpoints(m_options.m_ignore_count);
709 result.AppendMessageWithFormat("All watchpoints ignored. (%lu watchpoints)\n", num_watchpoints);
710 result.SetStatus (eReturnStatusSuccessFinishNoResult);
711 }
712 else
713 {
714 // Particular watchpoints selected; ignore them.
715 std::vector<uint32_t> wp_ids;
716 if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, wp_ids))
717 {
718 result.AppendError("Invalid watchpoints specification.");
719 result.SetStatus(eReturnStatusFailed);
720 return false;
721 }
722
723 int count = 0;
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))
727 ++count;
728 result.AppendMessageWithFormat("%d watchpoints ignored.\n",count);
729 result.SetStatus (eReturnStatusSuccessFinishNoResult);
730 }
731
732 return result.Succeeded();
733 }
734
735 private:
736 CommandOptions m_options;
737 };
738
739 #pragma mark Ignore::CommandOptions
740 OptionDefinition
741 CommandObjectWatchpointIgnore::CommandOptions::g_option_table[] =
742 {
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 }
745 };
746
747
748 //-------------------------------------------------------------------------
749 // CommandObjectWatchpointModify
750 //-------------------------------------------------------------------------
751 #pragma mark Modify
752
753 class CommandObjectWatchpointModify : public CommandObjectParsed
754 {
755 public:
756
CommandObjectWatchpointModify(CommandInterpreter & interpreter)757 CommandObjectWatchpointModify (CommandInterpreter &interpreter) :
758 CommandObjectParsed (interpreter,
759 "watchpoint modify",
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.",
763 NULL),
764 m_options (interpreter)
765 {
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);
770 }
771
772 virtual
~CommandObjectWatchpointModify()773 ~CommandObjectWatchpointModify () {}
774
775 virtual Options *
GetOptions()776 GetOptions ()
777 {
778 return &m_options;
779 }
780
781 class CommandOptions : public Options
782 {
783 public:
784
CommandOptions(CommandInterpreter & interpreter)785 CommandOptions (CommandInterpreter &interpreter) :
786 Options (interpreter),
787 m_condition (),
788 m_condition_passed (false)
789 {
790 }
791
792 virtual
~CommandOptions()793 ~CommandOptions () {}
794
795 virtual Error
SetOptionValue(uint32_t option_idx,const char * option_arg)796 SetOptionValue (uint32_t option_idx, const char *option_arg)
797 {
798 Error error;
799 const int short_option = m_getopt_table[option_idx].val;
800
801 switch (short_option)
802 {
803 case 'c':
804 if (option_arg != NULL)
805 m_condition.assign (option_arg);
806 else
807 m_condition.clear();
808 m_condition_passed = true;
809 break;
810 default:
811 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
812 break;
813 }
814
815 return error;
816 }
817
818 void
OptionParsingStarting()819 OptionParsingStarting ()
820 {
821 m_condition.clear();
822 m_condition_passed = false;
823 }
824
825 const OptionDefinition*
GetDefinitions()826 GetDefinitions ()
827 {
828 return g_option_table;
829 }
830
831 // Options table: Required for subclasses of Options.
832
833 static OptionDefinition g_option_table[];
834
835 // Instance variables to hold the values for command options.
836
837 std::string m_condition;
838 bool m_condition_passed;
839 };
840
841 protected:
842 virtual bool
DoExecute(Args & command,CommandReturnObject & result)843 DoExecute (Args& command, CommandReturnObject &result)
844 {
845 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
846 if (!CheckTargetForWatchpointOperations(target, result))
847 return false;
848
849 Mutex::Locker locker;
850 target->GetWatchpointList().GetListMutex(locker);
851
852 const WatchpointList &watchpoints = target->GetWatchpointList();
853
854 size_t num_watchpoints = watchpoints.GetSize();
855
856 if (num_watchpoints == 0)
857 {
858 result.AppendError("No watchpoints exist to be modified.");
859 result.SetStatus(eReturnStatusFailed);
860 return false;
861 }
862
863 if (command.GetArgumentCount() == 0)
864 {
865 WatchpointSP wp_sp = target->GetLastCreatedWatchpoint();
866 wp_sp->SetCondition(m_options.m_condition.c_str());
867 result.SetStatus (eReturnStatusSuccessFinishNoResult);
868 }
869 else
870 {
871 // Particular watchpoints selected; set condition on them.
872 std::vector<uint32_t> wp_ids;
873 if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, wp_ids))
874 {
875 result.AppendError("Invalid watchpoints specification.");
876 result.SetStatus(eReturnStatusFailed);
877 return false;
878 }
879
880 int count = 0;
881 const size_t size = wp_ids.size();
882 for (size_t i = 0; i < size; ++i)
883 {
884 WatchpointSP wp_sp = watchpoints.FindByID(wp_ids[i]);
885 if (wp_sp)
886 {
887 wp_sp->SetCondition(m_options.m_condition.c_str());
888 ++count;
889 }
890 }
891 result.AppendMessageWithFormat("%d watchpoints modified.\n",count);
892 result.SetStatus (eReturnStatusSuccessFinishNoResult);
893 }
894
895 return result.Succeeded();
896 }
897
898 private:
899 CommandOptions m_options;
900 };
901
902 #pragma mark Modify::CommandOptions
903 OptionDefinition
904 CommandObjectWatchpointModify::CommandOptions::g_option_table[] =
905 {
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 }
908 };
909
910 //-------------------------------------------------------------------------
911 // CommandObjectWatchpointSetVariable
912 //-------------------------------------------------------------------------
913 #pragma mark SetVariable
914
915 class CommandObjectWatchpointSetVariable : public CommandObjectParsed
916 {
917 public:
918
CommandObjectWatchpointSetVariable(CommandInterpreter & interpreter)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 "
927 "byte size. "
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.",
931 NULL,
932 eFlagRequiresFrame |
933 eFlagTryTargetAPILock |
934 eFlagProcessMustBeLaunched |
935 eFlagProcessMustBePaused ),
936 m_option_group (interpreter),
937 m_option_watchpoint ()
938 {
939 SetHelpLong(
940 "Examples: \n\
941 \n\
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");
944
945 CommandArgumentEntry arg;
946 CommandArgumentData var_name_arg;
947
948 // Define the only variant of this arg.
949 var_name_arg.arg_type = eArgTypeVarName;
950 var_name_arg.arg_repetition = eArgRepeatPlain;
951
952 // Push the variant into the argument entry.
953 arg.push_back (var_name_arg);
954
955 // Push the data for the only argument into the m_arguments vector.
956 m_arguments.push_back (arg);
957
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();
961 }
962
963 virtual
~CommandObjectWatchpointSetVariable()964 ~CommandObjectWatchpointSetVariable () {}
965
966 virtual Options *
GetOptions()967 GetOptions ()
968 {
969 return &m_option_group;
970 }
971
972 protected:
GetVariableCallback(void * baton,const char * name,VariableList & variable_list)973 static size_t GetVariableCallback (void *baton,
974 const char *name,
975 VariableList &variable_list)
976 {
977 Target *target = static_cast<Target *>(baton);
978 if (target)
979 {
980 return target->GetImages().FindGlobalVariables (ConstString(name),
981 true,
982 UINT32_MAX,
983 variable_list);
984 }
985 return 0;
986 }
987
988 virtual bool
DoExecute(Args & command,CommandReturnObject & result)989 DoExecute (Args& command, CommandReturnObject &result)
990 {
991 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
992 StackFrame *frame = m_exe_ctx.GetFramePtr();
993
994 // If no argument is present, issue an error message. There's no way to set a watchpoint.
995 if (command.GetArgumentCount() <= 0)
996 {
997 result.GetErrorStream().Printf("error: required argument missing; specify your program variable to watch for\n");
998 result.SetStatus(eReturnStatusFailed);
999 return false;
1000 }
1001
1002 // If no '-w' is specified, default to '-w write'.
1003 if (!m_option_watchpoint.watch_type_specified)
1004 {
1005 m_option_watchpoint.watch_type = OptionGroupWatchpoint::eWatchWrite;
1006 }
1007
1008 // We passed the sanity check for the command.
1009 // Proceed to set the watchpoint now.
1010 lldb::addr_t addr = 0;
1011 size_t size = 0;
1012
1013 VariableSP var_sp;
1014 ValueObjectSP valobj_sp;
1015 Stream &output_stream = result.GetOutputStream();
1016
1017 // A simple watch variable gesture allows only one argument.
1018 if (command.GetArgumentCount() != 1)
1019 {
1020 result.GetErrorStream().Printf("error: specify exactly one variable to watch for\n");
1021 result.SetStatus(eReturnStatusFailed);
1022 return false;
1023 }
1024
1025 // Things have checked out ok...
1026 Error error;
1027 uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember |
1028 StackFrame::eExpressionPathOptionsAllowDirectIVarAccess;
1029 valobj_sp = frame->GetValueForVariableExpressionPath (command.GetArgumentAtIndex(0),
1030 eNoDynamicValues,
1031 expr_path_options,
1032 var_sp,
1033 error);
1034
1035 if (!valobj_sp)
1036 {
1037 // Not in the frame; let's check the globals.
1038
1039 VariableList variable_list;
1040 ValueObjectList valobj_list;
1041
1042 Error error (Variable::GetValuesForVariableExpressionPath (command.GetArgumentAtIndex(0),
1043 m_exe_ctx.GetBestExecutionContextScope(),
1044 GetVariableCallback,
1045 target,
1046 variable_list,
1047 valobj_list));
1048
1049 if (valobj_list.GetSize())
1050 valobj_sp = valobj_list.GetValueObjectAtIndex(0);
1051 }
1052
1053 ClangASTType clang_type;
1054
1055 if (valobj_sp)
1056 {
1057 AddressType addr_type;
1058 addr = valobj_sp->GetAddressOf(false, &addr_type);
1059 if (addr_type == eAddressTypeLoad)
1060 {
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;
1065 }
1066 clang_type = valobj_sp->GetClangType();
1067 }
1068 else
1069 {
1070 const char *error_cstr = error.AsCString(NULL);
1071 if (error_cstr)
1072 result.GetErrorStream().Printf("error: %s\n", error_cstr);
1073 else
1074 result.GetErrorStream().Printf ("error: unable to find any variable expression path that matches '%s'\n",
1075 command.GetArgumentAtIndex(0));
1076 return false;
1077 }
1078
1079 // Now it's time to create the watchpoint.
1080 uint32_t watch_type = m_option_watchpoint.watch_type;
1081
1082 error.Clear();
1083 Watchpoint *wp = target->CreateWatchpoint(addr, size, &clang_type, watch_type, error).get();
1084 if (wp)
1085 {
1086 wp->SetWatchSpec(command.GetArgumentAtIndex(0));
1087 wp->SetWatchVariable(true);
1088 if (var_sp && var_sp->GetDeclaration().GetFile())
1089 {
1090 StreamString ss;
1091 // True to show fullpath for declaration file.
1092 var_sp->GetDeclaration().DumpStopContext(&ss, true);
1093 wp->SetDeclInfo(ss.GetString());
1094 }
1095 output_stream.Printf("Watchpoint created: ");
1096 wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull);
1097 output_stream.EOL();
1098 result.SetStatus(eReturnStatusSuccessFinishResult);
1099 }
1100 else
1101 {
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);
1107 }
1108
1109 return result.Succeeded();
1110 }
1111
1112 private:
1113 OptionGroupOptions m_option_group;
1114 OptionGroupWatchpoint m_option_watchpoint;
1115 };
1116
1117 //-------------------------------------------------------------------------
1118 // CommandObjectWatchpointSetExpression
1119 //-------------------------------------------------------------------------
1120 #pragma mark Set
1121
1122 class CommandObjectWatchpointSetExpression : public CommandObjectRaw
1123 {
1124 public:
1125
CommandObjectWatchpointSetExpression(CommandInterpreter & interpreter)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.",
1138 NULL,
1139 eFlagRequiresFrame |
1140 eFlagTryTargetAPILock |
1141 eFlagProcessMustBeLaunched |
1142 eFlagProcessMustBePaused ),
1143 m_option_group (interpreter),
1144 m_option_watchpoint ()
1145 {
1146 SetHelpLong(
1147 "Examples: \n\
1148 \n\
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");
1151
1152 CommandArgumentEntry arg;
1153 CommandArgumentData expression_arg;
1154
1155 // Define the only variant of this arg.
1156 expression_arg.arg_type = eArgTypeExpression;
1157 expression_arg.arg_repetition = eArgRepeatPlain;
1158
1159 // Push the only variant into the argument entry.
1160 arg.push_back (expression_arg);
1161
1162 // Push the data for the only argument into the m_arguments vector.
1163 m_arguments.push_back (arg);
1164
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();
1168 }
1169
1170
1171 virtual
~CommandObjectWatchpointSetExpression()1172 ~CommandObjectWatchpointSetExpression () {}
1173
1174 // Overrides base class's behavior where WantsCompletion = !WantsRawCommandString.
1175 virtual bool
WantsCompletion()1176 WantsCompletion() { return true; }
1177
1178 virtual Options *
GetOptions()1179 GetOptions ()
1180 {
1181 return &m_option_group;
1182 }
1183
1184 protected:
1185 virtual bool
DoExecute(const char * raw_command,CommandReturnObject & result)1186 DoExecute (const char *raw_command, CommandReturnObject &result)
1187 {
1188 m_option_group.NotifyOptionParsingStarting(); // This is a raw command, so notify the option group
1189
1190 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1191 StackFrame *frame = m_exe_ctx.GetFramePtr();
1192
1193 Args command(raw_command);
1194 const char *expr = NULL;
1195 if (raw_command[0] == '-')
1196 {
1197 // We have some options and these options MUST end with --.
1198 const char *end_options = NULL;
1199 const char *s = raw_command;
1200 while (s && s[0])
1201 {
1202 end_options = ::strstr (s, "--");
1203 if (end_options)
1204 {
1205 end_options += 2; // Get past the "--"
1206 if (::isspace (end_options[0]))
1207 {
1208 expr = end_options;
1209 while (::isspace (*expr))
1210 ++expr;
1211 break;
1212 }
1213 }
1214 s = end_options;
1215 }
1216
1217 if (end_options)
1218 {
1219 Args args (raw_command, end_options - raw_command);
1220 if (!ParseOptions (args, result))
1221 return false;
1222
1223 Error error (m_option_group.NotifyOptionParsingFinished());
1224 if (error.Fail())
1225 {
1226 result.AppendError (error.AsCString());
1227 result.SetStatus (eReturnStatusFailed);
1228 return false;
1229 }
1230 }
1231 }
1232
1233 if (expr == NULL)
1234 expr = raw_command;
1235
1236 // If no argument is present, issue an error message. There's no way to set a watchpoint.
1237 if (command.GetArgumentCount() == 0)
1238 {
1239 result.GetErrorStream().Printf("error: required argument missing; specify an expression to evaulate into the address to watch for\n");
1240 result.SetStatus(eReturnStatusFailed);
1241 return false;
1242 }
1243
1244 // If no '-w' is specified, default to '-w write'.
1245 if (!m_option_watchpoint.watch_type_specified)
1246 {
1247 m_option_watchpoint.watch_type = OptionGroupWatchpoint::eWatchWrite;
1248 }
1249
1250 // We passed the sanity check for the command.
1251 // Proceed to set the watchpoint now.
1252 lldb::addr_t addr = 0;
1253 size_t size = 0;
1254
1255 ValueObjectSP valobj_sp;
1256
1257 // Use expression evaluation to arrive at the address to watch.
1258 EvaluateExpressionOptions options;
1259 options.SetCoerceToId(false)
1260 .SetUnwindOnError(true)
1261 .SetKeepInMemory(false)
1262 .SetRunOthers(true)
1263 .SetTimeoutUsec(0);
1264
1265 ExecutionResults expr_result = target->EvaluateExpression (expr,
1266 frame,
1267 valobj_sp,
1268 options);
1269 if (expr_result != eExecutionCompleted)
1270 {
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);
1274 return false;
1275 }
1276
1277 // Get the address to watch.
1278 bool success = false;
1279 addr = valobj_sp->GetValueAsUnsigned(0, &success);
1280 if (!success)
1281 {
1282 result.GetErrorStream().Printf("error: expression did not evaluate to an address\n");
1283 result.SetStatus(eReturnStatusFailed);
1284 return false;
1285 }
1286
1287 if (m_option_watchpoint.watch_size != 0)
1288 size = m_option_watchpoint.watch_size;
1289 else
1290 size = target->GetArchitecture().GetAddressByteSize();
1291
1292 // Now it's time to create the watchpoint.
1293 uint32_t watch_type = m_option_watchpoint.watch_type;
1294
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());
1298
1299 Error error;
1300 Watchpoint *wp = target->CreateWatchpoint(addr, size, &clang_type, watch_type, error).get();
1301 if (wp)
1302 {
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);
1308 }
1309 else
1310 {
1311 result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%" PRIx64 ", size=%lu).\n",
1312 addr, size);
1313 if (error.AsCString(NULL))
1314 result.AppendError(error.AsCString());
1315 result.SetStatus(eReturnStatusFailed);
1316 }
1317
1318 return result.Succeeded();
1319 }
1320
1321 private:
1322 OptionGroupOptions m_option_group;
1323 OptionGroupWatchpoint m_option_watchpoint;
1324 };
1325
1326 //-------------------------------------------------------------------------
1327 // CommandObjectWatchpointSet
1328 //-------------------------------------------------------------------------
1329 #pragma mark Set
1330
1331 class CommandObjectWatchpointSet : public CommandObjectMultiword
1332 {
1333 public:
1334
CommandObjectWatchpointSet(CommandInterpreter & interpreter)1335 CommandObjectWatchpointSet (CommandInterpreter &interpreter) :
1336 CommandObjectMultiword (interpreter,
1337 "watchpoint set",
1338 "A set of commands for setting a watchpoint.",
1339 "watchpoint set <subcommand> [<subcommand-options>]")
1340 {
1341
1342 LoadSubCommand ("variable", CommandObjectSP (new CommandObjectWatchpointSetVariable (interpreter)));
1343 LoadSubCommand ("expression", CommandObjectSP (new CommandObjectWatchpointSetExpression (interpreter)));
1344 }
1345
1346
1347 virtual
~CommandObjectWatchpointSet()1348 ~CommandObjectWatchpointSet () {}
1349
1350 };
1351
1352 //-------------------------------------------------------------------------
1353 // CommandObjectMultiwordWatchpoint
1354 //-------------------------------------------------------------------------
1355 #pragma mark MultiwordWatchpoint
1356
CommandObjectMultiwordWatchpoint(CommandInterpreter & interpreter)1357 CommandObjectMultiwordWatchpoint::CommandObjectMultiwordWatchpoint(CommandInterpreter &interpreter) :
1358 CommandObjectMultiword (interpreter,
1359 "watchpoint",
1360 "A set of commands for operating on watchpoints.",
1361 "watchpoint <command> [<command-options>]")
1362 {
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));
1371
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");
1380
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);
1389 }
1390
~CommandObjectMultiwordWatchpoint()1391 CommandObjectMultiwordWatchpoint::~CommandObjectMultiwordWatchpoint()
1392 {
1393 }
1394
1395