]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/llvm/tools/lldb/source/Commands/CommandObjectWatchpoint.cpp
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / llvm / tools / lldb / source / Commands / CommandObjectWatchpoint.cpp
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
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
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"
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
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
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:
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
188     ~CommandObjectWatchpointList () {}
189
190     virtual Options *
191     GetOptions ()
192     {
193         return &m_options;
194     }
195
196     class CommandOptions : public Options
197     {
198     public:
199
200         CommandOptions (CommandInterpreter &interpreter) :
201             Options(interpreter),
202             m_level(lldb::eDescriptionLevelBrief) // Watchpoint List defaults to brief descriptions
203         {
204         }
205
206         virtual
207         ~CommandOptions () {}
208
209         virtual Error
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
235         OptionParsingStarting ()
236         {
237             m_level = lldb::eDescriptionLevelFull;
238         }
239
240         const OptionDefinition *
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
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:
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
371     ~CommandObjectWatchpointEnable () {}
372
373 protected:
374     virtual bool
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:
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
451     ~CommandObjectWatchpointDisable () {}
452
453 protected:
454     virtual bool
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:
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
534     ~CommandObjectWatchpointDelete () {}
535
536 protected:
537     virtual bool
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:
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
617     ~CommandObjectWatchpointIgnore () {}
618
619     virtual Options *
620     GetOptions ()
621     {
622         return &m_options;
623     }
624
625     class CommandOptions : public Options
626     {
627     public:
628
629         CommandOptions (CommandInterpreter &interpreter) :
630             Options (interpreter),
631             m_ignore_count (0)
632         {
633         }
634
635         virtual
636         ~CommandOptions () {}
637
638         virtual Error
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
662         OptionParsingStarting ()
663         {
664             m_ignore_count = 0;
665         }
666
667         const OptionDefinition *
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
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
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
773     ~CommandObjectWatchpointModify () {}
774
775     virtual Options *
776     GetOptions ()
777     {
778         return &m_options;
779     }
780
781     class CommandOptions : public Options
782     {
783     public:
784
785         CommandOptions (CommandInterpreter &interpreter) :
786             Options (interpreter),
787             m_condition (),
788             m_condition_passed (false)
789         {
790         }
791
792         virtual
793         ~CommandOptions () {}
794
795         virtual Error
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
819         OptionParsingStarting ()
820         {
821             m_condition.clear();
822             m_condition_passed = false;
823         }
824         
825         const OptionDefinition*
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
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
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
964     ~CommandObjectWatchpointSetVariable () {}
965
966     virtual Options *
967     GetOptions ()
968     {
969         return &m_option_group;
970     }
971
972 protected:
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
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
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
1172     ~CommandObjectWatchpointSetExpression () {}
1173
1174     // Overrides base class's behavior where WantsCompletion = !WantsRawCommandString.
1175     virtual bool
1176     WantsCompletion() { return true; }
1177
1178     virtual Options *
1179     GetOptions ()
1180     {
1181         return &m_option_group;
1182     }
1183
1184 protected:
1185     virtual bool
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
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
1348     ~CommandObjectWatchpointSet () {}
1349
1350 };
1351
1352 //-------------------------------------------------------------------------
1353 // CommandObjectMultiwordWatchpoint
1354 //-------------------------------------------------------------------------
1355 #pragma mark MultiwordWatchpoint
1356
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
1391 CommandObjectMultiwordWatchpoint::~CommandObjectMultiwordWatchpoint()
1392 {
1393 }
1394