blob: f63e4a85012fd9fd2a94963448ca6793d2648827 [file] [log] [blame]
Johnny Chen01acfa72011-09-22 18:04:58 +00001//===-- 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
Daniel Malead891f9b2012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Johnny Chen01acfa72011-09-22 18:04:58 +000012#include "CommandObjectWatchpoint.h"
Johnny Chenf3ec4612012-08-09 23:09:42 +000013#include "CommandObjectWatchpointCommand.h"
Johnny Chen01acfa72011-09-22 18:04:58 +000014
15// C Includes
16// C++ Includes
17// Other libraries and framework includes
18// Project includes
Johnny Chenecd4feb2011-10-14 00:42:25 +000019#include "lldb/Breakpoint/Watchpoint.h"
20#include "lldb/Breakpoint/WatchpointList.h"
Johnny Chen01acfa72011-09-22 18:04:58 +000021#include "lldb/Core/StreamString.h"
Johnny Chen55a2d5a2012-01-30 21:46:17 +000022#include "lldb/Core/ValueObject.h"
23#include "lldb/Core/ValueObjectVariable.h"
Johnny Chen01acfa72011-09-22 18:04:58 +000024#include "lldb/Interpreter/CommandInterpreter.h"
25#include "lldb/Interpreter/CommandReturnObject.h"
Johnny Chen01acfa72011-09-22 18:04:58 +000026#include "lldb/Interpreter/CommandCompletions.h"
Johnny Chen55a2d5a2012-01-30 21:46:17 +000027#include "lldb/Symbol/Variable.h"
28#include "lldb/Symbol/VariableList.h"
29#include "lldb/Target/Target.h"
Johnny Chen01acfa72011-09-22 18:04:58 +000030
31#include <vector>
32
33using namespace lldb;
34using namespace lldb_private;
35
36static void
Johnny Chenecd4feb2011-10-14 00:42:25 +000037AddWatchpointDescription(Stream *s, Watchpoint *wp, lldb::DescriptionLevel level)
Johnny Chen01acfa72011-09-22 18:04:58 +000038{
39 s->IndentMore();
Johnny Chenecd4feb2011-10-14 00:42:25 +000040 wp->GetDescription(s, level);
Johnny Chen01acfa72011-09-22 18:04:58 +000041 s->IndentLess();
42 s->EOL();
43}
44
45static bool
46CheckTargetForWatchpointOperations(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
Jim Inghamda26bd22012-06-08 21:56:10 +000065// FIXME: This doesn't seem to be the right place for this functionality.
Johnny Chen01acfa72011-09-22 18:04:58 +000066#include "llvm/ADT/StringRef.h"
Jim Inghamda26bd22012-06-08 21:56:10 +000067static inline void StripLeadingSpaces(llvm::StringRef &Str)
68{
69 while (!Str.empty() && isspace(Str[0]))
70 Str = Str.substr(1);
71}
72static inline llvm::StringRef StripOptionTerminator(llvm::StringRef &Str, bool with_dash_w, bool with_dash_x)
73{
74 llvm::StringRef ExprStr = Str;
75
76 // Get rid of the leading spaces first.
77 StripLeadingSpaces(ExprStr);
78
79 // If there's no '-w' and no '-x', we can just return.
80 if (!with_dash_w && !with_dash_x)
81 return ExprStr;
82
83 // Otherwise, split on the "--" option terminator string, and return the rest of the string.
84 ExprStr = ExprStr.split("--").second;
85 StripLeadingSpaces(ExprStr);
86 return ExprStr;
87}
88
Johnny Chen01acfa72011-09-22 18:04:58 +000089
90// Equivalent class: {"-", "to", "To", "TO"} of range specifier array.
91static const char* RSA[4] = { "-", "to", "To", "TO" };
92
93// Return the index to RSA if found; otherwise -1 is returned.
94static int32_t
95WithRSAIndex(llvm::StringRef &Arg)
96{
97
98 uint32_t i;
99 for (i = 0; i < 4; ++i)
100 if (Arg.find(RSA[i]) != llvm::StringRef::npos)
101 return i;
102 return -1;
103}
104
105// Return true if wp_ids is successfully populated with the watch ids.
106// False otherwise.
Johnny Chen10320892012-06-19 22:12:58 +0000107bool
108CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(Args &args, std::vector<uint32_t> &wp_ids)
Johnny Chen01acfa72011-09-22 18:04:58 +0000109{
110 // Pre-condition: args.GetArgumentCount() > 0.
111 assert(args.GetArgumentCount() > 0);
112
113 llvm::StringRef Minus("-");
114 std::vector<llvm::StringRef> StrRefArgs;
115 std::pair<llvm::StringRef, llvm::StringRef> Pair;
116 size_t i;
117 int32_t idx;
118 // Go through the argments and make a canonical form of arg list containing
119 // only numbers with possible "-" in between.
120 for (i = 0; i < args.GetArgumentCount(); ++i) {
121 llvm::StringRef Arg(args.GetArgumentAtIndex(i));
122 if ((idx = WithRSAIndex(Arg)) == -1) {
123 StrRefArgs.push_back(Arg);
124 continue;
125 }
126 // The Arg contains the range specifier, split it, then.
127 Pair = Arg.split(RSA[idx]);
128 if (!Pair.first.empty())
129 StrRefArgs.push_back(Pair.first);
130 StrRefArgs.push_back(Minus);
131 if (!Pair.second.empty())
132 StrRefArgs.push_back(Pair.second);
133 }
134 // Now process the canonical list and fill in the vector of uint32_t's.
135 // If there is any error, return false and the client should ignore wp_ids.
136 uint32_t beg, end, id;
137 size_t size = StrRefArgs.size();
138 bool in_range = false;
139 for (i = 0; i < size; ++i) {
140 llvm::StringRef Arg = StrRefArgs[i];
141 if (in_range) {
142 // Look for the 'end' of the range. Note StringRef::getAsInteger()
143 // returns true to signify error while parsing.
144 if (Arg.getAsInteger(0, end))
145 return false;
146 // Found a range! Now append the elements.
147 for (id = beg; id <= end; ++id)
148 wp_ids.push_back(id);
149 in_range = false;
150 continue;
151 }
152 if (i < (size - 1) && StrRefArgs[i+1] == Minus) {
153 if (Arg.getAsInteger(0, beg))
154 return false;
155 // Turn on the in_range flag, we are looking for end of range next.
156 ++i; in_range = true;
157 continue;
158 }
159 // Otherwise, we have a simple ID. Just append it.
160 if (Arg.getAsInteger(0, beg))
161 return false;
162 wp_ids.push_back(beg);
163 }
164 // It is an error if after the loop, we're still in_range.
165 if (in_range)
166 return false;
167
168 return true; // Success!
169}
170
171//-------------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000172// CommandObjectWatchpointList
173//-------------------------------------------------------------------------
174#pragma mark List
175
176class CommandObjectWatchpointList : public CommandObjectParsed
177{
178public:
179 CommandObjectWatchpointList (CommandInterpreter &interpreter) :
180 CommandObjectParsed (interpreter,
181 "watchpoint list",
182 "List all watchpoints at configurable levels of detail.",
183 NULL),
184 m_options(interpreter)
185 {
186 CommandArgumentEntry arg;
187 CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange);
188 // Add the entry for the first argument for this command to the object's arguments vector.
189 m_arguments.push_back(arg);
190 }
191
192 virtual
193 ~CommandObjectWatchpointList () {}
194
195 virtual Options *
196 GetOptions ()
197 {
198 return &m_options;
199 }
200
201 class CommandOptions : public Options
202 {
203 public:
204
205 CommandOptions (CommandInterpreter &interpreter) :
206 Options(interpreter),
207 m_level(lldb::eDescriptionLevelBrief) // Watchpoint List defaults to brief descriptions
208 {
209 }
210
211 virtual
212 ~CommandOptions () {}
213
214 virtual Error
215 SetOptionValue (uint32_t option_idx, const char *option_arg)
216 {
217 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +0000218 const int short_option = m_getopt_table[option_idx].val;
Jim Inghamda26bd22012-06-08 21:56:10 +0000219
220 switch (short_option)
221 {
222 case 'b':
223 m_level = lldb::eDescriptionLevelBrief;
224 break;
225 case 'f':
226 m_level = lldb::eDescriptionLevelFull;
227 break;
228 case 'v':
229 m_level = lldb::eDescriptionLevelVerbose;
230 break;
231 default:
232 error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
233 break;
234 }
235
236 return error;
237 }
238
239 void
240 OptionParsingStarting ()
241 {
242 m_level = lldb::eDescriptionLevelFull;
243 }
244
245 const OptionDefinition *
246 GetDefinitions ()
247 {
248 return g_option_table;
249 }
250
251
252 // Options table: Required for subclasses of Options.
253
254 static OptionDefinition g_option_table[];
255
256 // Instance variables to hold the values for command options.
257
258 lldb::DescriptionLevel m_level;
259 };
260
261protected:
262 virtual bool
263 DoExecute (Args& command, CommandReturnObject &result)
264 {
265 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
266 if (target == NULL)
267 {
268 result.AppendError ("Invalid target. No current target or watchpoints.");
269 result.SetStatus (eReturnStatusSuccessFinishNoResult);
270 return true;
271 }
272
273 if (target->GetProcessSP() && target->GetProcessSP()->IsAlive())
274 {
275 uint32_t num_supported_hardware_watchpoints;
276 Error error = target->GetProcessSP()->GetWatchpointSupportInfo(num_supported_hardware_watchpoints);
277 if (error.Success())
278 result.AppendMessageWithFormat("Number of supported hardware watchpoints: %u\n",
279 num_supported_hardware_watchpoints);
280 }
281
282 const WatchpointList &watchpoints = target->GetWatchpointList();
283 Mutex::Locker locker;
284 target->GetWatchpointList().GetListMutex(locker);
285
286 size_t num_watchpoints = watchpoints.GetSize();
287
288 if (num_watchpoints == 0)
289 {
290 result.AppendMessage("No watchpoints currently set.");
291 result.SetStatus(eReturnStatusSuccessFinishNoResult);
292 return true;
293 }
294
295 Stream &output_stream = result.GetOutputStream();
296
297 if (command.GetArgumentCount() == 0)
298 {
299 // No watchpoint selected; show info about all currently set watchpoints.
300 result.AppendMessage ("Current watchpoints:");
301 for (size_t i = 0; i < num_watchpoints; ++i)
302 {
303 Watchpoint *wp = watchpoints.GetByIndex(i).get();
304 AddWatchpointDescription(&output_stream, wp, m_options.m_level);
305 }
306 result.SetStatus(eReturnStatusSuccessFinishNoResult);
307 }
308 else
309 {
310 // Particular watchpoints selected; enable them.
311 std::vector<uint32_t> wp_ids;
Johnny Chen10320892012-06-19 22:12:58 +0000312 if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(command, wp_ids))
Jim Inghamda26bd22012-06-08 21:56:10 +0000313 {
314 result.AppendError("Invalid watchpoints specification.");
315 result.SetStatus(eReturnStatusFailed);
316 return false;
317 }
318
319 const size_t size = wp_ids.size();
320 for (size_t i = 0; i < size; ++i)
321 {
322 Watchpoint *wp = watchpoints.FindByID(wp_ids[i]).get();
323 if (wp)
324 AddWatchpointDescription(&output_stream, wp, m_options.m_level);
325 result.SetStatus(eReturnStatusSuccessFinishNoResult);
326 }
327 }
328
329 return result.Succeeded();
330 }
331
332private:
333 CommandOptions m_options;
334};
335
336//-------------------------------------------------------------------------
337// CommandObjectWatchpointList::Options
338//-------------------------------------------------------------------------
339#pragma mark List::CommandOptions
340OptionDefinition
341CommandObjectWatchpointList::CommandOptions::g_option_table[] =
342{
343 { LLDB_OPT_SET_1, false, "brief", 'b', no_argument, NULL, 0, eArgTypeNone,
344 "Give a brief description of the watchpoint (no location info)."},
345
346 { LLDB_OPT_SET_2, false, "full", 'f', no_argument, NULL, 0, eArgTypeNone,
347 "Give a full description of the watchpoint and its locations."},
348
349 { LLDB_OPT_SET_3, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone,
350 "Explain everything we know about the watchpoint (for debugging debugger bugs)." },
351
352 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
353};
354
355//-------------------------------------------------------------------------
356// CommandObjectWatchpointEnable
357//-------------------------------------------------------------------------
358#pragma mark Enable
359
360class CommandObjectWatchpointEnable : public CommandObjectParsed
361{
362public:
363 CommandObjectWatchpointEnable (CommandInterpreter &interpreter) :
364 CommandObjectParsed (interpreter,
365 "enable",
366 "Enable the specified disabled watchpoint(s). If no watchpoints are specified, enable all of them.",
367 NULL)
368 {
369 CommandArgumentEntry arg;
370 CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange);
371 // Add the entry for the first argument for this command to the object's arguments vector.
372 m_arguments.push_back(arg);
373 }
374
375 virtual
376 ~CommandObjectWatchpointEnable () {}
377
378protected:
379 virtual bool
380 DoExecute (Args& command,
381 CommandReturnObject &result)
382 {
383 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
384 if (!CheckTargetForWatchpointOperations(target, result))
385 return false;
386
387 Mutex::Locker locker;
388 target->GetWatchpointList().GetListMutex(locker);
389
390 const WatchpointList &watchpoints = target->GetWatchpointList();
391
392 size_t num_watchpoints = watchpoints.GetSize();
393
394 if (num_watchpoints == 0)
395 {
396 result.AppendError("No watchpoints exist to be enabled.");
397 result.SetStatus(eReturnStatusFailed);
398 return false;
399 }
400
401 if (command.GetArgumentCount() == 0)
402 {
403 // No watchpoint selected; enable all currently set watchpoints.
404 target->EnableAllWatchpoints();
405 result.AppendMessageWithFormat("All watchpoints enabled. (%lu watchpoints)\n", num_watchpoints);
406 result.SetStatus(eReturnStatusSuccessFinishNoResult);
407 }
408 else
409 {
410 // Particular watchpoints selected; enable them.
411 std::vector<uint32_t> wp_ids;
Johnny Chen10320892012-06-19 22:12:58 +0000412 if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(command, wp_ids))
Jim Inghamda26bd22012-06-08 21:56:10 +0000413 {
414 result.AppendError("Invalid watchpoints specification.");
415 result.SetStatus(eReturnStatusFailed);
416 return false;
417 }
418
419 int count = 0;
420 const size_t size = wp_ids.size();
421 for (size_t i = 0; i < size; ++i)
422 if (target->EnableWatchpointByID(wp_ids[i]))
423 ++count;
424 result.AppendMessageWithFormat("%d watchpoints enabled.\n", count);
425 result.SetStatus(eReturnStatusSuccessFinishNoResult);
426 }
427
428 return result.Succeeded();
429 }
430
431private:
432};
433
434//-------------------------------------------------------------------------
435// CommandObjectWatchpointDisable
436//-------------------------------------------------------------------------
437#pragma mark Disable
438
439class CommandObjectWatchpointDisable : public CommandObjectParsed
440{
441public:
442 CommandObjectWatchpointDisable (CommandInterpreter &interpreter) :
443 CommandObjectParsed (interpreter,
444 "watchpoint disable",
445 "Disable the specified watchpoint(s) without removing it/them. If no watchpoints are specified, disable them all.",
446 NULL)
447 {
448 CommandArgumentEntry arg;
449 CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange);
450 // Add the entry for the first argument for this command to the object's arguments vector.
451 m_arguments.push_back(arg);
452 }
453
454
455 virtual
456 ~CommandObjectWatchpointDisable () {}
457
458protected:
459 virtual bool
460 DoExecute (Args& command, CommandReturnObject &result)
461 {
462 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
463 if (!CheckTargetForWatchpointOperations(target, result))
464 return false;
465
466 Mutex::Locker locker;
467 target->GetWatchpointList().GetListMutex(locker);
468
469 const WatchpointList &watchpoints = target->GetWatchpointList();
470 size_t num_watchpoints = watchpoints.GetSize();
471
472 if (num_watchpoints == 0)
473 {
474 result.AppendError("No watchpoints exist to be disabled.");
475 result.SetStatus(eReturnStatusFailed);
476 return false;
477 }
478
479 if (command.GetArgumentCount() == 0)
480 {
481 // No watchpoint selected; disable all currently set watchpoints.
482 if (target->DisableAllWatchpoints())
483 {
484 result.AppendMessageWithFormat("All watchpoints disabled. (%lu watchpoints)\n", num_watchpoints);
485 result.SetStatus(eReturnStatusSuccessFinishNoResult);
486 }
487 else
488 {
489 result.AppendError("Disable all watchpoints failed\n");
490 result.SetStatus(eReturnStatusFailed);
491 }
492 }
493 else
494 {
495 // Particular watchpoints selected; disable them.
496 std::vector<uint32_t> wp_ids;
Johnny Chen10320892012-06-19 22:12:58 +0000497 if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(command, wp_ids))
Jim Inghamda26bd22012-06-08 21:56:10 +0000498 {
499 result.AppendError("Invalid watchpoints specification.");
500 result.SetStatus(eReturnStatusFailed);
501 return false;
502 }
503
504 int count = 0;
505 const size_t size = wp_ids.size();
506 for (size_t i = 0; i < size; ++i)
507 if (target->DisableWatchpointByID(wp_ids[i]))
508 ++count;
509 result.AppendMessageWithFormat("%d watchpoints disabled.\n", count);
510 result.SetStatus(eReturnStatusSuccessFinishNoResult);
511 }
512
513 return result.Succeeded();
514 }
515
516};
517
518//-------------------------------------------------------------------------
519// CommandObjectWatchpointDelete
520//-------------------------------------------------------------------------
521#pragma mark Delete
522
523class CommandObjectWatchpointDelete : public CommandObjectParsed
524{
525public:
526 CommandObjectWatchpointDelete (CommandInterpreter &interpreter) :
527 CommandObjectParsed(interpreter,
528 "watchpoint delete",
529 "Delete the specified watchpoint(s). If no watchpoints are specified, delete them all.",
530 NULL)
531 {
532 CommandArgumentEntry arg;
533 CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange);
534 // Add the entry for the first argument for this command to the object's arguments vector.
535 m_arguments.push_back(arg);
536 }
537
538 virtual
539 ~CommandObjectWatchpointDelete () {}
540
541protected:
542 virtual bool
543 DoExecute (Args& command, CommandReturnObject &result)
544 {
545 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
546 if (!CheckTargetForWatchpointOperations(target, result))
547 return false;
548
549 Mutex::Locker locker;
550 target->GetWatchpointList().GetListMutex(locker);
551
552 const WatchpointList &watchpoints = target->GetWatchpointList();
553
554 size_t num_watchpoints = watchpoints.GetSize();
555
556 if (num_watchpoints == 0)
557 {
558 result.AppendError("No watchpoints exist to be deleted.");
559 result.SetStatus(eReturnStatusFailed);
560 return false;
561 }
562
563 if (command.GetArgumentCount() == 0)
564 {
565 if (!m_interpreter.Confirm("About to delete all watchpoints, do you want to do that?", true))
566 {
567 result.AppendMessage("Operation cancelled...");
568 }
569 else
570 {
571 target->RemoveAllWatchpoints();
572 result.AppendMessageWithFormat("All watchpoints removed. (%lu watchpoints)\n", num_watchpoints);
573 }
574 result.SetStatus (eReturnStatusSuccessFinishNoResult);
575 }
576 else
577 {
578 // Particular watchpoints selected; delete them.
579 std::vector<uint32_t> wp_ids;
Johnny Chen10320892012-06-19 22:12:58 +0000580 if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(command, wp_ids))
Jim Inghamda26bd22012-06-08 21:56:10 +0000581 {
582 result.AppendError("Invalid watchpoints specification.");
583 result.SetStatus(eReturnStatusFailed);
584 return false;
585 }
586
587 int count = 0;
588 const size_t size = wp_ids.size();
589 for (size_t i = 0; i < size; ++i)
590 if (target->RemoveWatchpointByID(wp_ids[i]))
591 ++count;
592 result.AppendMessageWithFormat("%d watchpoints deleted.\n",count);
593 result.SetStatus (eReturnStatusSuccessFinishNoResult);
594 }
595
596 return result.Succeeded();
597 }
598
599};
600
601//-------------------------------------------------------------------------
602// CommandObjectWatchpointIgnore
603//-------------------------------------------------------------------------
604
605class CommandObjectWatchpointIgnore : public CommandObjectParsed
606{
607public:
608 CommandObjectWatchpointIgnore (CommandInterpreter &interpreter) :
609 CommandObjectParsed (interpreter,
610 "watchpoint ignore",
611 "Set ignore count on the specified watchpoint(s). If no watchpoints are specified, set them all.",
612 NULL),
613 m_options (interpreter)
614 {
615 CommandArgumentEntry arg;
616 CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange);
617 // Add the entry for the first argument for this command to the object's arguments vector.
618 m_arguments.push_back(arg);
619 }
620
621 virtual
622 ~CommandObjectWatchpointIgnore () {}
623
624 virtual Options *
625 GetOptions ()
626 {
627 return &m_options;
628 }
629
630 class CommandOptions : public Options
631 {
632 public:
633
634 CommandOptions (CommandInterpreter &interpreter) :
635 Options (interpreter),
636 m_ignore_count (0)
637 {
638 }
639
640 virtual
641 ~CommandOptions () {}
642
643 virtual Error
644 SetOptionValue (uint32_t option_idx, const char *option_arg)
645 {
646 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +0000647 const int short_option = m_getopt_table[option_idx].val;
Jim Inghamda26bd22012-06-08 21:56:10 +0000648
649 switch (short_option)
650 {
651 case 'i':
652 {
653 m_ignore_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
654 if (m_ignore_count == UINT32_MAX)
655 error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
656 }
657 break;
658 default:
659 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
660 break;
661 }
662
663 return error;
664 }
665
666 void
667 OptionParsingStarting ()
668 {
669 m_ignore_count = 0;
670 }
671
672 const OptionDefinition *
673 GetDefinitions ()
674 {
675 return g_option_table;
676 }
677
678
679 // Options table: Required for subclasses of Options.
680
681 static OptionDefinition g_option_table[];
682
683 // Instance variables to hold the values for command options.
684
685 uint32_t m_ignore_count;
686 };
687
688protected:
689 virtual bool
690 DoExecute (Args& command,
691 CommandReturnObject &result)
692 {
693 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
694 if (!CheckTargetForWatchpointOperations(target, result))
695 return false;
696
697 Mutex::Locker locker;
698 target->GetWatchpointList().GetListMutex(locker);
699
700 const WatchpointList &watchpoints = target->GetWatchpointList();
701
702 size_t num_watchpoints = watchpoints.GetSize();
703
704 if (num_watchpoints == 0)
705 {
706 result.AppendError("No watchpoints exist to be ignored.");
707 result.SetStatus(eReturnStatusFailed);
708 return false;
709 }
710
711 if (command.GetArgumentCount() == 0)
712 {
713 target->IgnoreAllWatchpoints(m_options.m_ignore_count);
714 result.AppendMessageWithFormat("All watchpoints ignored. (%lu watchpoints)\n", num_watchpoints);
715 result.SetStatus (eReturnStatusSuccessFinishNoResult);
716 }
717 else
718 {
719 // Particular watchpoints selected; ignore them.
720 std::vector<uint32_t> wp_ids;
Johnny Chen10320892012-06-19 22:12:58 +0000721 if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(command, wp_ids))
Jim Inghamda26bd22012-06-08 21:56:10 +0000722 {
723 result.AppendError("Invalid watchpoints specification.");
724 result.SetStatus(eReturnStatusFailed);
725 return false;
726 }
727
728 int count = 0;
729 const size_t size = wp_ids.size();
730 for (size_t i = 0; i < size; ++i)
731 if (target->IgnoreWatchpointByID(wp_ids[i], m_options.m_ignore_count))
732 ++count;
733 result.AppendMessageWithFormat("%d watchpoints ignored.\n",count);
734 result.SetStatus (eReturnStatusSuccessFinishNoResult);
735 }
736
737 return result.Succeeded();
738 }
739
740private:
741 CommandOptions m_options;
742};
743
744#pragma mark Ignore::CommandOptions
745OptionDefinition
746CommandObjectWatchpointIgnore::CommandOptions::g_option_table[] =
747{
Filipe Cabecinhas560c5142012-09-11 16:09:27 +0000748 { LLDB_OPT_SET_ALL, true, "ignore-count", 'i', required_argument, NULL, 0, eArgTypeCount, "Set the number of times this watchpoint is skipped before stopping." },
Jim Inghamda26bd22012-06-08 21:56:10 +0000749 { 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL }
750};
751
752
753//-------------------------------------------------------------------------
754// CommandObjectWatchpointModify
755//-------------------------------------------------------------------------
756#pragma mark Modify
757
758class CommandObjectWatchpointModify : public CommandObjectParsed
759{
760public:
761
762 CommandObjectWatchpointModify (CommandInterpreter &interpreter) :
763 CommandObjectParsed (interpreter,
764 "watchpoint modify",
765 "Modify the options on a watchpoint or set of watchpoints in the executable. "
766 "If no watchpoint is specified, act on the last created watchpoint. "
767 "Passing an empty argument clears the modification.",
768 NULL),
769 m_options (interpreter)
770 {
771 CommandArgumentEntry arg;
772 CommandObject::AddIDsArgumentData(arg, eArgTypeWatchpointID, eArgTypeWatchpointIDRange);
773 // Add the entry for the first argument for this command to the object's arguments vector.
774 m_arguments.push_back (arg);
775 }
776
777 virtual
778 ~CommandObjectWatchpointModify () {}
779
780 virtual Options *
781 GetOptions ()
782 {
783 return &m_options;
784 }
785
786 class CommandOptions : public Options
787 {
788 public:
789
790 CommandOptions (CommandInterpreter &interpreter) :
791 Options (interpreter),
792 m_condition (),
793 m_condition_passed (false)
794 {
795 }
796
797 virtual
798 ~CommandOptions () {}
799
800 virtual Error
801 SetOptionValue (uint32_t option_idx, const char *option_arg)
802 {
803 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +0000804 const int short_option = m_getopt_table[option_idx].val;
Jim Inghamda26bd22012-06-08 21:56:10 +0000805
806 switch (short_option)
807 {
808 case 'c':
809 if (option_arg != NULL)
810 m_condition.assign (option_arg);
811 else
812 m_condition.clear();
813 m_condition_passed = true;
814 break;
815 default:
816 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
817 break;
818 }
819
820 return error;
821 }
822
823 void
824 OptionParsingStarting ()
825 {
826 m_condition.clear();
827 m_condition_passed = false;
828 }
829
830 const OptionDefinition*
831 GetDefinitions ()
832 {
833 return g_option_table;
834 }
835
836 // Options table: Required for subclasses of Options.
837
838 static OptionDefinition g_option_table[];
839
840 // Instance variables to hold the values for command options.
841
842 std::string m_condition;
843 bool m_condition_passed;
844 };
845
846protected:
847 virtual bool
848 DoExecute (Args& command, CommandReturnObject &result)
849 {
850 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
851 if (!CheckTargetForWatchpointOperations(target, result))
852 return false;
853
854 Mutex::Locker locker;
855 target->GetWatchpointList().GetListMutex(locker);
856
857 const WatchpointList &watchpoints = target->GetWatchpointList();
858
859 size_t num_watchpoints = watchpoints.GetSize();
860
861 if (num_watchpoints == 0)
862 {
863 result.AppendError("No watchpoints exist to be modified.");
864 result.SetStatus(eReturnStatusFailed);
865 return false;
866 }
867
868 if (command.GetArgumentCount() == 0)
869 {
870 WatchpointSP wp_sp = target->GetLastCreatedWatchpoint();
871 wp_sp->SetCondition(m_options.m_condition.c_str());
872 result.SetStatus (eReturnStatusSuccessFinishNoResult);
873 }
874 else
875 {
876 // Particular watchpoints selected; set condition on them.
877 std::vector<uint32_t> wp_ids;
Johnny Chen10320892012-06-19 22:12:58 +0000878 if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(command, wp_ids))
Jim Inghamda26bd22012-06-08 21:56:10 +0000879 {
880 result.AppendError("Invalid watchpoints specification.");
881 result.SetStatus(eReturnStatusFailed);
882 return false;
883 }
884
885 int count = 0;
886 const size_t size = wp_ids.size();
887 for (size_t i = 0; i < size; ++i)
888 {
889 WatchpointSP wp_sp = watchpoints.FindByID(wp_ids[i]);
890 if (wp_sp)
891 {
892 wp_sp->SetCondition(m_options.m_condition.c_str());
893 ++count;
894 }
895 }
896 result.AppendMessageWithFormat("%d watchpoints modified.\n",count);
897 result.SetStatus (eReturnStatusSuccessFinishNoResult);
898 }
899
900 return result.Succeeded();
901 }
902
903private:
904 CommandOptions m_options;
905};
906
907#pragma mark Modify::CommandOptions
908OptionDefinition
909CommandObjectWatchpointModify::CommandOptions::g_option_table[] =
910{
Filipe Cabecinhas560c5142012-09-11 16:09:27 +0000911{ LLDB_OPT_SET_ALL, false, "condition", 'c', required_argument, NULL, 0, eArgTypeExpression, "The watchpoint stops only if this condition expression evaluates to true."},
Jim Inghamda26bd22012-06-08 21:56:10 +0000912{ 0, false, NULL, 0 , 0, NULL, 0, eArgTypeNone, NULL }
913};
914
915//-------------------------------------------------------------------------
916// CommandObjectWatchpointSetVariable
917//-------------------------------------------------------------------------
918#pragma mark SetVariable
919
920class CommandObjectWatchpointSetVariable : public CommandObjectParsed
921{
922public:
923
924 CommandObjectWatchpointSetVariable (CommandInterpreter &interpreter) :
925 CommandObjectParsed (interpreter,
926 "watchpoint set variable",
927 "Set a watchpoint on a variable. "
928 "Use the '-w' option to specify the type of watchpoint and "
929 "the '-x' option to specify the byte size to watch for. "
Johnny Chen26a24b72012-06-29 19:35:01 +0000930 "If no '-w' option is specified, it defaults to write. "
Jim Inghamda26bd22012-06-08 21:56:10 +0000931 "If no '-x' option is specified, it defaults to the variable's "
932 "byte size. "
933 "Note that there are limited hardware resources for watchpoints. "
934 "If watchpoint setting fails, consider disable/delete existing ones "
935 "to free up resources.",
936 NULL,
937 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
938 m_option_group (interpreter),
939 m_option_watchpoint ()
940 {
941 SetHelpLong(
942 "Examples: \n\
943 \n\
944 watchpoint set variable -w read_wriate my_global_var \n\
945 # Watch my_global_var for read/write access, with the region to watch corresponding to the byte size of the data type.\n");
946
947 CommandArgumentEntry arg;
948 CommandArgumentData var_name_arg;
949
950 // Define the only variant of this arg.
951 var_name_arg.arg_type = eArgTypeVarName;
952 var_name_arg.arg_repetition = eArgRepeatPlain;
953
954 // Push the variant into the argument entry.
955 arg.push_back (var_name_arg);
956
957 // Push the data for the only argument into the m_arguments vector.
958 m_arguments.push_back (arg);
959
960 // Absorb the '-w' and '-x' options into our option group.
961 m_option_group.Append (&m_option_watchpoint, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
962 m_option_group.Finalize();
963 }
964
965 virtual
966 ~CommandObjectWatchpointSetVariable () {}
967
968 virtual Options *
969 GetOptions ()
970 {
971 return &m_option_group;
972 }
973
974protected:
Sean Callanan0b5a40c2012-09-14 17:20:18 +0000975 static uint32_t GetVariableCallback (void *baton,
976 const char *name,
977 VariableList &variable_list)
978 {
979 Target *target = static_cast<Target *>(baton);
980 if (target)
981 {
982 return target->GetImages().FindGlobalVariables (ConstString(name),
983 true,
984 UINT32_MAX,
985 variable_list);
986 }
987 return 0;
988 }
989
Jim Inghamda26bd22012-06-08 21:56:10 +0000990 virtual bool
991 DoExecute (Args& command,
992 CommandReturnObject &result)
993 {
994 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
995 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
996 StackFrame *frame = exe_ctx.GetFramePtr();
997 if (frame == NULL)
998 {
999 result.AppendError ("you must be stopped in a valid stack frame to set a watchpoint.");
1000 result.SetStatus (eReturnStatusFailed);
1001 return false;
1002 }
1003
1004 // If no argument is present, issue an error message. There's no way to set a watchpoint.
1005 if (command.GetArgumentCount() <= 0)
1006 {
1007 result.GetErrorStream().Printf("error: required argument missing; specify your program variable to watch for\n");
1008 result.SetStatus(eReturnStatusFailed);
1009 return false;
1010 }
1011
Johnny Chen26a24b72012-06-29 19:35:01 +00001012 // If no '-w' is specified, default to '-w write'.
Jim Inghamda26bd22012-06-08 21:56:10 +00001013 if (!m_option_watchpoint.watch_type_specified)
1014 {
Johnny Chen26a24b72012-06-29 19:35:01 +00001015 m_option_watchpoint.watch_type = OptionGroupWatchpoint::eWatchWrite;
Jim Inghamda26bd22012-06-08 21:56:10 +00001016 }
1017
1018 // We passed the sanity check for the command.
1019 // Proceed to set the watchpoint now.
1020 lldb::addr_t addr = 0;
1021 size_t size = 0;
1022
1023 VariableSP var_sp;
1024 ValueObjectSP valobj_sp;
1025 Stream &output_stream = result.GetOutputStream();
1026
1027 // A simple watch variable gesture allows only one argument.
1028 if (command.GetArgumentCount() != 1) {
1029 result.GetErrorStream().Printf("error: specify exactly one variable to watch for\n");
1030 result.SetStatus(eReturnStatusFailed);
1031 return false;
1032 }
1033
1034 // Things have checked out ok...
1035 Error error;
Greg Claytonb3a1a2b2012-07-14 00:53:55 +00001036 uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember |
1037 StackFrame::eExpressionPathOptionsAllowDirectIVarAccess;
Jim Inghamda26bd22012-06-08 21:56:10 +00001038 valobj_sp = frame->GetValueForVariableExpressionPath (command.GetArgumentAtIndex(0),
1039 eNoDynamicValues,
1040 expr_path_options,
1041 var_sp,
1042 error);
Sean Callanan0b5a40c2012-09-14 17:20:18 +00001043
1044 if (!valobj_sp) {
1045 // Not in the frame; let's check the globals.
1046
1047 VariableList variable_list;
1048 ValueObjectList valobj_list;
1049
1050 Error error (Variable::GetValuesForVariableExpressionPath (command.GetArgumentAtIndex(0),
1051 exe_ctx.GetBestExecutionContextScope(),
1052 GetVariableCallback,
1053 target,
1054 variable_list,
1055 valobj_list));
1056
1057 if (valobj_list.GetSize())
1058 valobj_sp = valobj_list.GetValueObjectAtIndex(0);
1059 }
1060
Jim Ingham9e376622012-10-23 07:20:06 +00001061 ClangASTType type;
1062
Jim Inghamda26bd22012-06-08 21:56:10 +00001063 if (valobj_sp) {
1064 AddressType addr_type;
1065 addr = valobj_sp->GetAddressOf(false, &addr_type);
1066 if (addr_type == eAddressTypeLoad) {
1067 // We're in business.
1068 // Find out the size of this variable.
1069 size = m_option_watchpoint.watch_size == 0 ? valobj_sp->GetByteSize()
1070 : m_option_watchpoint.watch_size;
1071 }
Jim Ingham9e376622012-10-23 07:20:06 +00001072 type.SetClangType(valobj_sp->GetClangAST(), valobj_sp->GetClangType());
Jim Inghamda26bd22012-06-08 21:56:10 +00001073 } else {
1074 const char *error_cstr = error.AsCString(NULL);
1075 if (error_cstr)
1076 result.GetErrorStream().Printf("error: %s\n", error_cstr);
1077 else
1078 result.GetErrorStream().Printf ("error: unable to find any variable expression path that matches '%s'\n",
1079 command.GetArgumentAtIndex(0));
1080 return false;
1081 }
1082
1083 // Now it's time to create the watchpoint.
1084 uint32_t watch_type = m_option_watchpoint.watch_type;
1085 error.Clear();
Jim Ingham9e376622012-10-23 07:20:06 +00001086 Watchpoint *wp = target->CreateWatchpoint(addr, size, &type, watch_type, error).get();
Jim Inghamda26bd22012-06-08 21:56:10 +00001087 if (wp) {
Johnny Chen9e985592012-08-13 21:09:54 +00001088 wp->SetWatchSpec(command.GetArgumentAtIndex(0));
1089 wp->SetWatchVariable(true);
Jim Inghamda26bd22012-06-08 21:56:10 +00001090 if (var_sp && var_sp->GetDeclaration().GetFile()) {
1091 StreamString ss;
1092 // True to show fullpath for declaration file.
1093 var_sp->GetDeclaration().DumpStopContext(&ss, true);
1094 wp->SetDeclInfo(ss.GetString());
1095 }
Jim Inghamda26bd22012-06-08 21:56:10 +00001096 output_stream.Printf("Watchpoint created: ");
1097 wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull);
1098 output_stream.EOL();
1099 result.SetStatus(eReturnStatusSuccessFinishResult);
1100 } else {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001101 result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%" PRIx64 ", size=%lu, variable expression='%s').\n",
Johnny Chen9e985592012-08-13 21:09:54 +00001102 addr, size, command.GetArgumentAtIndex(0));
Jim Inghamda26bd22012-06-08 21:56:10 +00001103 if (error.AsCString(NULL))
1104 result.AppendError(error.AsCString());
1105 result.SetStatus(eReturnStatusFailed);
1106 }
1107
1108 return result.Succeeded();
1109 }
1110
1111private:
1112 OptionGroupOptions m_option_group;
1113 OptionGroupWatchpoint m_option_watchpoint;
1114};
1115
1116//-------------------------------------------------------------------------
1117// CommandObjectWatchpointSetExpression
1118//-------------------------------------------------------------------------
1119#pragma mark Set
1120
1121class CommandObjectWatchpointSetExpression : public CommandObjectRaw
1122{
1123public:
1124
1125 CommandObjectWatchpointSetExpression (CommandInterpreter &interpreter) :
1126 CommandObjectRaw (interpreter,
1127 "watchpoint set expression",
1128 "Set a watchpoint on an address by supplying an expression. "
1129 "Use the '-w' option to specify the type of watchpoint and "
1130 "the '-x' option to specify the byte size to watch for. "
Johnny Chen26a24b72012-06-29 19:35:01 +00001131 "If no '-w' option is specified, it defaults to write. "
Jim Inghamda26bd22012-06-08 21:56:10 +00001132 "If no '-x' option is specified, it defaults to the target's "
1133 "pointer byte size. "
1134 "Note that there are limited hardware resources for watchpoints. "
1135 "If watchpoint setting fails, consider disable/delete existing ones "
1136 "to free up resources.",
1137 NULL,
1138 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
1139 m_option_group (interpreter),
1140 m_option_watchpoint ()
1141 {
1142 SetHelpLong(
1143 "Examples: \n\
1144 \n\
1145 watchpoint set expression -w write -x 1 -- foo + 32\n\
1146 # Watch write access for the 1-byte region pointed to by the address 'foo + 32'.\n");
1147
1148 CommandArgumentEntry arg;
1149 CommandArgumentData expression_arg;
1150
1151 // Define the only variant of this arg.
1152 expression_arg.arg_type = eArgTypeExpression;
1153 expression_arg.arg_repetition = eArgRepeatPlain;
1154
1155 // Push the only variant into the argument entry.
1156 arg.push_back (expression_arg);
1157
1158 // Push the data for the only argument into the m_arguments vector.
1159 m_arguments.push_back (arg);
1160
1161 // Absorb the '-w' and '-x' options into our option group.
1162 m_option_group.Append (&m_option_watchpoint, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
1163 m_option_group.Finalize();
1164 }
1165
1166
1167 virtual
1168 ~CommandObjectWatchpointSetExpression () {}
1169
1170 // Overrides base class's behavior where WantsCompletion = !WantsRawCommandString.
1171 virtual bool
1172 WantsCompletion() { return true; }
1173
1174 virtual Options *
1175 GetOptions ()
1176 {
1177 return &m_option_group;
1178 }
1179
1180protected:
1181 virtual bool
1182 DoExecute (const char *raw_command, CommandReturnObject &result)
1183 {
1184 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1185 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
1186 StackFrame *frame = exe_ctx.GetFramePtr();
1187 if (frame == NULL)
1188 {
1189 result.AppendError ("you must be stopped in a valid stack frame to set a watchpoint.");
1190 result.SetStatus (eReturnStatusFailed);
1191 return false;
1192 }
1193
1194 Args command(raw_command);
1195
1196 // Process possible options.
1197 if (!ParseOptions (command, result))
1198 return false;
1199
1200 // If no argument is present, issue an error message. There's no way to set a watchpoint.
1201 if (command.GetArgumentCount() <= 0)
1202 {
1203 result.GetErrorStream().Printf("error: required argument missing; specify an expression to evaulate into the addres to watch for\n");
1204 result.SetStatus(eReturnStatusFailed);
1205 return false;
1206 }
1207
1208 bool with_dash_w = m_option_watchpoint.watch_type_specified;
1209 bool with_dash_x = (m_option_watchpoint.watch_size != 0);
1210
Johnny Chen26a24b72012-06-29 19:35:01 +00001211 // If no '-w' is specified, default to '-w write'.
Jim Inghamda26bd22012-06-08 21:56:10 +00001212 if (!with_dash_w)
1213 {
Johnny Chen26a24b72012-06-29 19:35:01 +00001214 m_option_watchpoint.watch_type = OptionGroupWatchpoint::eWatchWrite;
Jim Inghamda26bd22012-06-08 21:56:10 +00001215 }
1216
1217 // We passed the sanity check for the command.
1218 // Proceed to set the watchpoint now.
1219 lldb::addr_t addr = 0;
1220 size_t size = 0;
1221
1222 VariableSP var_sp;
1223 ValueObjectSP valobj_sp;
1224 Stream &output_stream = result.GetOutputStream();
1225
1226 // We will process the raw command string to rid of the '-w', '-x', or '--'
1227 llvm::StringRef raw_expr_str(raw_command);
1228 std::string expr_str = StripOptionTerminator(raw_expr_str, with_dash_w, with_dash_x).str();
1229
1230 // Sanity check for when the user forgets to terminate the option strings with a '--'.
1231 if ((with_dash_w || with_dash_w) && expr_str.empty())
1232 {
1233 result.GetErrorStream().Printf("error: did you forget to enter the option terminator string \"--\"?\n");
1234 result.SetStatus(eReturnStatusFailed);
1235 return false;
1236 }
1237
1238 // Use expression evaluation to arrive at the address to watch.
Jim Ingham47beabb2012-10-16 21:41:58 +00001239 EvaluateExpressionOptions options;
Enrico Granatad27026e2012-09-05 20:41:26 +00001240 options.SetCoerceToId(false)
1241 .SetUnwindOnError(true)
1242 .SetKeepInMemory(false)
Jim Ingham47beabb2012-10-16 21:41:58 +00001243 .SetRunOthers(true)
1244 .SetTimeoutUsec(0);
Enrico Granatad27026e2012-09-05 20:41:26 +00001245
Jim Inghamda26bd22012-06-08 21:56:10 +00001246 ExecutionResults expr_result = target->EvaluateExpression (expr_str.c_str(),
1247 frame,
Enrico Granata6cca9692012-07-16 23:10:35 +00001248 valobj_sp,
Enrico Granatad27026e2012-09-05 20:41:26 +00001249 options);
Jim Inghamda26bd22012-06-08 21:56:10 +00001250 if (expr_result != eExecutionCompleted) {
1251 result.GetErrorStream().Printf("error: expression evaluation of address to watch failed\n");
1252 result.GetErrorStream().Printf("expression evaluated: %s\n", expr_str.c_str());
1253 result.SetStatus(eReturnStatusFailed);
1254 return false;
1255 }
1256
1257 // Get the address to watch.
1258 bool success = false;
1259 addr = valobj_sp->GetValueAsUnsigned(0, &success);
1260 if (!success) {
1261 result.GetErrorStream().Printf("error: expression did not evaluate to an address\n");
1262 result.SetStatus(eReturnStatusFailed);
1263 return false;
1264 }
1265 size = with_dash_x ? m_option_watchpoint.watch_size
1266 : target->GetArchitecture().GetAddressByteSize();
1267
1268 // Now it's time to create the watchpoint.
1269 uint32_t watch_type = m_option_watchpoint.watch_type;
Jim Ingham9e376622012-10-23 07:20:06 +00001270
1271 // Fetch the type from the value object, the type of the watched object is the pointee type
1272 /// of the expression, so convert to that if we found a valid type.
1273 ClangASTType type(valobj_sp->GetClangAST(), valobj_sp->GetClangType());
1274 if (type.IsValid())
1275 type.SetClangType(type.GetASTContext(), type.GetPointeeType());
1276
Jim Inghamda26bd22012-06-08 21:56:10 +00001277 Error error;
Jim Ingham9e376622012-10-23 07:20:06 +00001278 Watchpoint *wp = target->CreateWatchpoint(addr, size, &type, watch_type, error).get();
Jim Inghamda26bd22012-06-08 21:56:10 +00001279 if (wp) {
1280 if (var_sp && var_sp->GetDeclaration().GetFile()) {
1281 StreamString ss;
1282 // True to show fullpath for declaration file.
1283 var_sp->GetDeclaration().DumpStopContext(&ss, true);
1284 wp->SetDeclInfo(ss.GetString());
1285 }
Jim Inghamda26bd22012-06-08 21:56:10 +00001286 output_stream.Printf("Watchpoint created: ");
1287 wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull);
1288 output_stream.EOL();
1289 result.SetStatus(eReturnStatusSuccessFinishResult);
1290 } else {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001291 result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%" PRIx64 ", size=%lu).\n",
Jim Inghamda26bd22012-06-08 21:56:10 +00001292 addr, size);
1293 if (error.AsCString(NULL))
1294 result.AppendError(error.AsCString());
1295 result.SetStatus(eReturnStatusFailed);
1296 }
1297
1298 return result.Succeeded();
1299 }
1300
1301private:
1302 OptionGroupOptions m_option_group;
1303 OptionGroupWatchpoint m_option_watchpoint;
1304};
1305
1306//-------------------------------------------------------------------------
1307// CommandObjectWatchpointSet
1308//-------------------------------------------------------------------------
1309#pragma mark Set
1310
1311class CommandObjectWatchpointSet : public CommandObjectMultiword
1312{
1313public:
1314
1315 CommandObjectWatchpointSet (CommandInterpreter &interpreter) :
1316 CommandObjectMultiword (interpreter,
1317 "watchpoint set",
1318 "A set of commands for setting a watchpoint.",
1319 "watchpoint set <subcommand> [<subcommand-options>]")
1320 {
1321
1322 LoadSubCommand ("variable", CommandObjectSP (new CommandObjectWatchpointSetVariable (interpreter)));
1323 LoadSubCommand ("expression", CommandObjectSP (new CommandObjectWatchpointSetExpression (interpreter)));
1324 }
1325
1326
1327 virtual
1328 ~CommandObjectWatchpointSet () {}
1329
1330};
1331
1332//-------------------------------------------------------------------------
Johnny Chen01acfa72011-09-22 18:04:58 +00001333// CommandObjectMultiwordWatchpoint
1334//-------------------------------------------------------------------------
1335#pragma mark MultiwordWatchpoint
1336
1337CommandObjectMultiwordWatchpoint::CommandObjectMultiwordWatchpoint(CommandInterpreter &interpreter) :
1338 CommandObjectMultiword (interpreter,
1339 "watchpoint",
1340 "A set of commands for operating on watchpoints.",
1341 "watchpoint <command> [<command-options>]")
1342{
Johnny Chen01acfa72011-09-22 18:04:58 +00001343 CommandObjectSP list_command_object (new CommandObjectWatchpointList (interpreter));
1344 CommandObjectSP enable_command_object (new CommandObjectWatchpointEnable (interpreter));
1345 CommandObjectSP disable_command_object (new CommandObjectWatchpointDisable (interpreter));
1346 CommandObjectSP delete_command_object (new CommandObjectWatchpointDelete (interpreter));
Johnny Chene14cf4e2011-10-05 21:35:46 +00001347 CommandObjectSP ignore_command_object (new CommandObjectWatchpointIgnore (interpreter));
Johnny Chenf3ec4612012-08-09 23:09:42 +00001348 CommandObjectSP command_command_object (new CommandObjectWatchpointCommand (interpreter));
Johnny Chen712a6282011-10-17 18:58:00 +00001349 CommandObjectSP modify_command_object (new CommandObjectWatchpointModify (interpreter));
Johnny Chen55a2d5a2012-01-30 21:46:17 +00001350 CommandObjectSP set_command_object (new CommandObjectWatchpointSet (interpreter));
Johnny Chen01acfa72011-09-22 18:04:58 +00001351
1352 list_command_object->SetCommandName ("watchpoint list");
1353 enable_command_object->SetCommandName("watchpoint enable");
1354 disable_command_object->SetCommandName("watchpoint disable");
1355 delete_command_object->SetCommandName("watchpoint delete");
Johnny Chene14cf4e2011-10-05 21:35:46 +00001356 ignore_command_object->SetCommandName("watchpoint ignore");
Johnny Chenf3ec4612012-08-09 23:09:42 +00001357 command_command_object->SetCommandName ("watchpoint command");
Johnny Chen712a6282011-10-17 18:58:00 +00001358 modify_command_object->SetCommandName("watchpoint modify");
Johnny Chen55a2d5a2012-01-30 21:46:17 +00001359 set_command_object->SetCommandName("watchpoint set");
Johnny Chen01acfa72011-09-22 18:04:58 +00001360
Greg Clayton4a379b12012-07-17 03:23:13 +00001361 LoadSubCommand ("list", list_command_object);
1362 LoadSubCommand ("enable", enable_command_object);
1363 LoadSubCommand ("disable", disable_command_object);
1364 LoadSubCommand ("delete", delete_command_object);
1365 LoadSubCommand ("ignore", ignore_command_object);
Johnny Chenf3ec4612012-08-09 23:09:42 +00001366 LoadSubCommand ("command", command_command_object);
Greg Clayton4a379b12012-07-17 03:23:13 +00001367 LoadSubCommand ("modify", modify_command_object);
1368 LoadSubCommand ("set", set_command_object);
Johnny Chen01acfa72011-09-22 18:04:58 +00001369}
1370
1371CommandObjectMultiwordWatchpoint::~CommandObjectMultiwordWatchpoint()
1372{
1373}
1374