1f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen//===-- CommandObjectWatchpointCommand.cpp ----------------------*- C++ -*-===//
2f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen//
3f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen//                     The LLVM Compiler Infrastructure
4f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen//
5f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen// This file is distributed under the University of Illinois Open Source
6f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen// License. See LICENSE.TXT for details.
7f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen//
8f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen//===----------------------------------------------------------------------===//
9f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
10d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea#include "lldb/lldb-python.h"
11d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea
12f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen// C Includes
13f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen// C++ Includes
14f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
15f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
16f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen#include "CommandObjectWatchpointCommand.h"
17f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen#include "CommandObjectWatchpoint.h"
18f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
19f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen#include "lldb/Interpreter/CommandInterpreter.h"
20f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen#include "lldb/Interpreter/CommandReturnObject.h"
21f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen#include "lldb/Target/Target.h"
22f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen#include "lldb/Target/Thread.h"
23f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen#include "lldb/Breakpoint/Watchpoint.h"
24f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen#include "lldb/Breakpoint/StoppointCallbackContext.h"
25f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen#include "lldb/Core/State.h"
26f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
27f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen#include <vector>
28f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
29f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenusing namespace lldb;
30f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenusing namespace lldb_private;
31f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
32f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen//-------------------------------------------------------------------------
33f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen// CommandObjectWatchpointCommandAdd
34f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen//-------------------------------------------------------------------------
35f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
36f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
37f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenclass CommandObjectWatchpointCommandAdd : public CommandObjectParsed
38f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen{
39f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenpublic:
40f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
41f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    CommandObjectWatchpointCommandAdd (CommandInterpreter &interpreter) :
42f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        CommandObjectParsed (interpreter,
43f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                             "add",
44f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                             "Add a set of commands to a watchpoint, to be executed whenever the watchpoint is hit.",
45f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                             NULL),
46f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        m_options (interpreter)
47f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    {
48f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        SetHelpLong (
49f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen"\nGeneral information about entering watchpoint commands \n\
50f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen------------------------------------------------------ \n\
51f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen \n\
52f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenThis command will cause you to be prompted to enter the command or set \n\
53f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenof commands you wish to be executed when the specified watchpoint is \n\
54f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenhit.  You will be told to enter your command(s), and will see a '> ' \n\
55f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenprompt. Because you can enter one or many commands to be executed when \n\
56f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chena watchpoint is hit, you will continue to be prompted after each \n\
57f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chennew-line that you enter, until you enter the word 'DONE', which will \n\
58f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chencause the commands you have entered to be stored with the watchpoint \n\
59f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenand executed when the watchpoint is hit. \n\
60f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen \n\
61f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenSyntax checking is not necessarily done when watchpoint commands are \n\
62f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenentered.  An improperly written watchpoint command will attempt to get \n\
63f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenexecuted when the watchpoint gets hit, and usually silently fail.  If \n\
64f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenyour watchpoint command does not appear to be getting executed, go \n\
65f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenback and check your syntax. \n\
66f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen \n\
67f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen \n\
68f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenSpecial information about PYTHON watchpoint commands                            \n\
69f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen----------------------------------------------------                            \n\
70f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                                                                \n\
71f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenYou may enter either one line of Python or multiple lines of Python             \n\
72f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen(including defining whole functions, if desired).  If you enter a               \n\
73f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chensingle line of Python, that will be passed to the Python interpreter            \n\
74f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen'as is' when the watchpoint gets hit.  If you enter function                    \n\
75f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chendefinitions, they will be passed to the Python interpreter as soon as           \n\
76f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenyou finish entering the watchpoint command, and they can be called              \n\
77f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenlater (don't forget to add calls to them, if you want them called when          \n\
78f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenthe watchpoint is hit).  If you enter multiple lines of Python that             \n\
79f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenare not function definitions, they will be collected into a new,                \n\
80f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenautomatically generated Python function, and a call to the newly                \n\
81f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chengenerated function will be attached to the watchpoint.                          \n\
82f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                                                                \n\
83f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenThis auto-generated function is passed in two arguments:                        \n\
84f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                                                                \n\
85f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    frame:  an SBFrame object representing the frame which hit the watchpoint.  \n\
86f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            From the frame you can get back to the thread and process.          \n\
87f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    wp:     the watchpoint that was hit.                                        \n\
88f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                                                                \n\
89f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenImportant Note: Because loose Python code gets collected into functions,        \n\
90f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenif you want to access global variables in the 'loose' code, you need to         \n\
91f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenspecify that they are global, using the 'global' keyword.  Be sure to           \n\
92f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenuse correct Python syntax, including indentation, when entering Python          \n\
93f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenwatchpoint commands.                                                            \n\
94f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                                                                \n\
95f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenAs a third option, you can pass the name of an already existing Python function \n\
96f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenand that function will be attached to the watchpoint. It will get passed the    \n\
97f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenframe and wp_loc arguments mentioned above.                                     \n\
98f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                                                                \n\
99f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenExample Python one-line watchpoint command: \n\
100f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen \n\
101f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen(lldb) watchpoint command add -s python 1 \n\
102f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenEnter your Python command(s). Type 'DONE' to end. \n\
103f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen> print \"Hit this watchpoint!\" \n\
104f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen> DONE \n\
105f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen \n\
106f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenAs a convenience, this also works for a short Python one-liner: \n\
107f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen(lldb) watchpoint command add -s python 1 -o \"import time; print time.asctime()\" \n\
108f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen(lldb) run \n\
109f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenLaunching '.../a.out'  (x86_64) \n\
110f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen(lldb) Fri Sep 10 12:17:45 2010 \n\
111f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenProcess 21778 Stopped \n\
112f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen* thread #1: tid = 0x2e03, 0x0000000100000de8 a.out`c + 7 at main.c:39, stop reason = watchpoint 1.1, queue = com.apple.main-thread \n\
113f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen  36   	\n\
114f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen  37   	int c(int val)\n\
115f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen  38   	{\n\
116f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen  39 ->	    return val + 3;\n\
117f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen  40   	}\n\
118f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen  41   	\n\
119f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen  42   	int main (int argc, char const *argv[])\n\
120f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen(lldb) \n\
121f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen \n\
122f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenExample multiple line Python watchpoint command, using function definition: \n\
123f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen \n\
124f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen(lldb) watchpoint command add -s python 1 \n\
125f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenEnter your Python command(s). Type 'DONE' to end. \n\
126f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen> def watchpoint_output (wp_no): \n\
127f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen>     out_string = \"Hit watchpoint number \" + repr (wp_no) \n\
128f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen>     print out_string \n\
129f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen>     return True \n\
130f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen> watchpoint_output (1) \n\
131f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen> DONE \n\
132f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen \n\
133f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen \n\
134f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenExample multiple line Python watchpoint command, using 'loose' Python: \n\
135f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen \n\
136f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen(lldb) watchpoint command add -s p 1 \n\
137f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenEnter your Python command(s). Type 'DONE' to end. \n\
138f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen> global wp_count \n\
139f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen> wp_count = wp_count + 1 \n\
140f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen> print \"Hit this watchpoint \" + repr(wp_count) + \" times!\" \n\
141f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen> DONE \n\
142f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen \n\
143f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenIn this case, since there is a reference to a global variable, \n\
144f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen'wp_count', you will also need to make sure 'wp_count' exists and is \n\
145f3ec4617297810223deb545cb68214ca4dd8009cJohnny Cheninitialized: \n\
146f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen \n\
147f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen(lldb) script \n\
148f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen>>> wp_count = 0 \n\
149f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen>>> quit() \n\
150f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen \n\
151f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen(lldb)  \n\
152f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen \n\
153f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen \n\
154f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenFinal Note:  If you get a warning that no watchpoint command was generated, \n\
155f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenbut you did not get any syntax errors, you probably forgot to add a call \n\
156f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chento your functions. \n\
157f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen \n\
158f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenSpecial information about debugger command watchpoint commands \n\
159f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen-------------------------------------------------------------- \n\
160f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen \n\
161f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenYou may enter any debugger command, exactly as you would at the \n\
162f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chendebugger prompt.  You may enter as many debugger commands as you like, \n\
163f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenbut do NOT enter more than one command per line. \n" );
164f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
165f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        CommandArgumentEntry arg;
166f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        CommandArgumentData wp_id_arg;
167f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
168f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        // Define the first (and only) variant of this arg.
169f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        wp_id_arg.arg_type = eArgTypeWatchpointID;
170f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        wp_id_arg.arg_repetition = eArgRepeatPlain;
171f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
172f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        // There is only one variant this argument could be; put it into the argument entry.
173f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        arg.push_back (wp_id_arg);
174f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
175f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        // Push the data for the first argument into the m_arguments vector.
176f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        m_arguments.push_back (arg);
177f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    }
178f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
179f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    virtual
180f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    ~CommandObjectWatchpointCommandAdd () {}
181f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
182f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    virtual Options *
183f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    GetOptions ()
184f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    {
185f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        return &m_options;
186f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    }
187f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
188f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    void
189f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    CollectDataForWatchpointCommandCallback (WatchpointOptions *wp_options,
190f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                             CommandReturnObject &result)
191f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    {
192f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
193102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton        std::unique_ptr<WatchpointOptions::CommandData> data_ap(new WatchpointOptions::CommandData());
194f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        if (reader_sp && data_ap.get())
195f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        {
196f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            BatonSP baton_sp (new WatchpointOptions::CommandBaton (data_ap.release()));
197f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            wp_options->SetCallback (WatchpointOptionsCallbackFunction, baton_sp);
198f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
199f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            Error err (reader_sp->Initialize (CommandObjectWatchpointCommandAdd::GenerateWatchpointCommandCallback,
200f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                              wp_options,                   // callback_data
201f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                              eInputReaderGranularityLine,  // token size, to pass to callback function
202f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                              "DONE",                       // end token
203f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                              "> ",                         // prompt
204f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                              true));                       // echo input
205f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            if (err.Success())
206f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            {
207f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                m_interpreter.GetDebugger().PushInputReader (reader_sp);
208f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                result.SetStatus (eReturnStatusSuccessFinishNoResult);
209f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            }
210f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            else
211f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            {
212f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                result.AppendError (err.AsCString());
213f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                result.SetStatus (eReturnStatusFailed);
214f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            }
215f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        }
216f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        else
217f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        {
218f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.AppendError("out of memory");
219f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.SetStatus (eReturnStatusFailed);
220f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        }
221f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
222f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    }
223f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
224f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    /// Set a one-liner as the callback for the watchpoint.
225f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    void
226f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    SetWatchpointCommandCallback (WatchpointOptions *wp_options,
227f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                  const char *oneliner)
228f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    {
229102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton        std::unique_ptr<WatchpointOptions::CommandData> data_ap(new WatchpointOptions::CommandData());
230f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
231f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        // It's necessary to set both user_source and script_source to the oneliner.
232f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        // The former is used to generate callback description (as in watchpoint command list)
233f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        // while the latter is used for Python to interpret during the actual callback.
234f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        data_ap->user_source.AppendString (oneliner);
235f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        data_ap->script_source.assign (oneliner);
236f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        data_ap->stop_on_error = m_options.m_stop_on_error;
237f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
238f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        BatonSP baton_sp (new WatchpointOptions::CommandBaton (data_ap.release()));
239f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        wp_options->SetCallback (WatchpointOptionsCallbackFunction, baton_sp);
240f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
241f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        return;
242f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    }
243f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
244f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    static size_t
245f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    GenerateWatchpointCommandCallback (void *callback_data,
246f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                       InputReader &reader,
247f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                       lldb::InputReaderAction notification,
248f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                       const char *bytes,
249f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                       size_t bytes_len)
250f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    {
251f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
252f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
253f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
254f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        switch (notification)
255f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        {
256f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        case eInputReaderActivate:
257f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            if (!batch_mode)
258f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            {
259f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                out_stream->Printf ("%s\n", g_reader_instructions);
260f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                if (reader.GetPrompt())
261f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    out_stream->Printf ("%s", reader.GetPrompt());
262f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                out_stream->Flush();
263f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            }
264f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            break;
265f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
266f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        case eInputReaderDeactivate:
267f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            break;
268f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
269f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        case eInputReaderReactivate:
270f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            if (reader.GetPrompt() && !batch_mode)
271f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            {
272f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                out_stream->Printf ("%s", reader.GetPrompt());
273f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                out_stream->Flush();
274f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            }
275f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            break;
276f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
277f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        case eInputReaderAsynchronousOutputWritten:
278f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            break;
279f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
280f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        case eInputReaderGotToken:
281f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            if (bytes && bytes_len && callback_data)
282f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            {
283f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                WatchpointOptions *wp_options = (WatchpointOptions *) callback_data;
284f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                if (wp_options)
285f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                {
286f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    Baton *wp_options_baton = wp_options->GetBaton();
287f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    if (wp_options_baton)
288f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                        ((WatchpointOptions::CommandData *)wp_options_baton->m_data)->user_source.AppendString (bytes, bytes_len);
289f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                }
290f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            }
291f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            if (!reader.IsDone() && reader.GetPrompt() && !batch_mode)
292f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            {
293f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                out_stream->Printf ("%s", reader.GetPrompt());
294f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                out_stream->Flush();
295f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            }
296f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            break;
297f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
298f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        case eInputReaderInterrupt:
299f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            {
300f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                // Finish, and cancel the watchpoint command.
301f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                reader.SetIsDone (true);
302f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                WatchpointOptions *wp_options = (WatchpointOptions *) callback_data;
303f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                if (wp_options)
304f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                {
305f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    Baton *wp_options_baton = wp_options->GetBaton ();
306f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    if (wp_options_baton)
307f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    {
308f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                        ((WatchpointOptions::CommandData *) wp_options_baton->m_data)->user_source.Clear();
309f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                        ((WatchpointOptions::CommandData *) wp_options_baton->m_data)->script_source.clear();
310f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    }
311f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                }
312f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                if (!batch_mode)
313f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                {
314f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    out_stream->Printf ("Warning: No command attached to watchpoint.\n");
315f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    out_stream->Flush();
316f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                }
317f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            }
318f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            break;
319f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
320f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        case eInputReaderEndOfFile:
321f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            reader.SetIsDone (true);
322f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            break;
323f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
324f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        case eInputReaderDone:
325f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            break;
326f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        }
327f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
328f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        return bytes_len;
329f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    }
330f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
331f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    static bool
332f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    WatchpointOptionsCallbackFunction (void *baton,
333f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                       StoppointCallbackContext *context,
334f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                       lldb::user_id_t watch_id)
335f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    {
336f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        bool ret_value = true;
337f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        if (baton == NULL)
338f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            return true;
339f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
340f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
341f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        WatchpointOptions::CommandData *data = (WatchpointOptions::CommandData *) baton;
342f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        StringList &commands = data->user_source;
343f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
344f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        if (commands.GetSize() > 0)
345f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        {
346f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            ExecutionContext exe_ctx (context->exe_ctx_ref);
347f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            Target *target = exe_ctx.GetTargetPtr();
348f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            if (target)
349f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            {
350f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                CommandReturnObject result;
351f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                Debugger &debugger = target->GetDebugger();
352f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                // Rig up the results secondary output stream to the debugger's, so the output will come out synchronously
353f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                // if the debugger is set up that way.
354f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
355f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                StreamSP output_stream (debugger.GetAsyncOutputStream());
356f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                StreamSP error_stream (debugger.GetAsyncErrorStream());
357f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                result.SetImmediateOutputStream (output_stream);
358f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                result.SetImmediateErrorStream (error_stream);
359f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
360f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                bool stop_on_continue = true;
361f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                bool echo_commands    = false;
362f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                bool print_results    = true;
363f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
364f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                debugger.GetCommandInterpreter().HandleCommands (commands,
365f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                                                 &exe_ctx,
366f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                                                 stop_on_continue,
367f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                                                 data->stop_on_error,
368f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                                                 echo_commands,
369f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                                                 print_results,
370f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                                                 eLazyBoolNo,
371f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                                                 result);
372f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                result.GetImmediateOutputStream()->Flush();
373f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                result.GetImmediateErrorStream()->Flush();
374f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen           }
375f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        }
376f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        return ret_value;
377f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    }
378f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
379f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    class CommandOptions : public Options
380f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    {
381f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    public:
382f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
383f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        CommandOptions (CommandInterpreter &interpreter) :
384f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            Options (interpreter),
385f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            m_use_commands (false),
386f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            m_use_script_language (false),
387f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            m_script_language (eScriptLanguageNone),
388f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            m_use_one_liner (false),
389f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            m_one_liner(),
390f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            m_function_name()
391f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        {
392f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        }
393f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
394f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        virtual
395f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        ~CommandOptions () {}
396f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
397f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        virtual Error
398f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        SetOptionValue (uint32_t option_idx, const char *option_arg)
399f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        {
400f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            Error error;
4016475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton            const int short_option = m_getopt_table[option_idx].val;
402f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
403f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            switch (short_option)
404f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            {
405f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            case 'o':
406f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                m_use_one_liner = true;
407f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                m_one_liner = option_arg;
408f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                break;
409f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
410f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            case 's':
411f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                m_script_language = (lldb::ScriptLanguage) Args::StringToOptionEnum (option_arg,
412f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                                                                     g_option_table[option_idx].enum_values,
413f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                                                                     eScriptLanguageNone,
414f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                                                                     error);
415f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
416f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                if (m_script_language == eScriptLanguagePython || m_script_language == eScriptLanguageDefault)
417f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                {
418f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    m_use_script_language = true;
419f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                }
420f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                else
421f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                {
422f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    m_use_script_language = false;
423f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                }
424f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                break;
425f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
426f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            case 'e':
427f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                {
428f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    bool success = false;
429f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    m_stop_on_error = Args::StringToBoolean(option_arg, false, &success);
430f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    if (!success)
431f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                        error.SetErrorStringWithFormat("invalid value for stop-on-error: \"%s\"", option_arg);
432f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                }
433f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                break;
434f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
435f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            case 'F':
436f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                {
437f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    m_use_one_liner = false;
438f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    m_use_script_language = true;
439f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    m_function_name.assign(option_arg);
440f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                }
441f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                break;
442f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
443f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            default:
444f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                break;
445f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            }
446f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            return error;
447f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        }
448f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        void
449f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        OptionParsingStarting ()
450f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        {
451f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            m_use_commands = true;
452f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            m_use_script_language = false;
453f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            m_script_language = eScriptLanguageNone;
454f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
455f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            m_use_one_liner = false;
456f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            m_stop_on_error = true;
457f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            m_one_liner.clear();
458f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            m_function_name.clear();
459f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        }
460f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
461f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        const OptionDefinition*
462f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        GetDefinitions ()
463f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        {
464f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            return g_option_table;
465f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        }
466f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
467f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        // Options table: Required for subclasses of Options.
468f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
469f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        static OptionDefinition g_option_table[];
470f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
471f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        // Instance variables to hold the values for command options.
472f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
473f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        bool m_use_commands;
474f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        bool m_use_script_language;
475f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        lldb::ScriptLanguage m_script_language;
476f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
477f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        // Instance variables to hold the values for one_liner options.
478f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        bool m_use_one_liner;
479f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        std::string m_one_liner;
480f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        bool m_stop_on_error;
481f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        std::string m_function_name;
482f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    };
483f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
484f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenprotected:
485f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    virtual bool
486f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    DoExecute (Args& command, CommandReturnObject &result)
487f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    {
488f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
489f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
490f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        if (target == NULL)
491f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        {
492f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.AppendError ("There is not a current executable; there are no watchpoints to which to add commands");
493f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.SetStatus (eReturnStatusFailed);
494f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            return false;
495f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        }
496f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
497f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        const WatchpointList &watchpoints = target->GetWatchpointList();
498f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        size_t num_watchpoints = watchpoints.GetSize();
499f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
500f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        if (num_watchpoints == 0)
501f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        {
502f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.AppendError ("No watchpoints exist to have commands added");
503f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.SetStatus (eReturnStatusFailed);
504f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            return false;
505f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        }
506f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
507f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        if (m_options.m_use_script_language == false && m_options.m_function_name.size())
508f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        {
509f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.AppendError ("need to enable scripting to have a function run as a watchpoint command");
510f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.SetStatus (eReturnStatusFailed);
511f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            return false;
512f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        }
513f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
514f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        std::vector<uint32_t> valid_wp_ids;
515bf1bec6263157c86b5df7d6b19090571ed7885a3Jim Ingham        if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, valid_wp_ids))
516f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        {
517f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.AppendError("Invalid watchpoints specification.");
518f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.SetStatus(eReturnStatusFailed);
519f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            return false;
520f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        }
521f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
522f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        result.SetStatus(eReturnStatusSuccessFinishNoResult);
523f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        const size_t count = valid_wp_ids.size();
524f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        for (size_t i = 0; i < count; ++i)
525f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        {
526f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            uint32_t cur_wp_id = valid_wp_ids.at (i);
527f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            if (cur_wp_id != LLDB_INVALID_WATCH_ID)
528f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            {
529f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                Watchpoint *wp = target->GetWatchpointList().FindByID (cur_wp_id).get();
530f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                // Sanity check wp first.
531f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                if (wp == NULL) continue;
532f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
533f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                WatchpointOptions *wp_options = wp->GetOptions();
534f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                // Skip this watchpoint if wp_options is not good.
535f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                if (wp_options == NULL) continue;
536f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
537f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                // If we are using script language, get the script interpreter
538f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                // in order to set or collect command callback.  Otherwise, call
539f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                // the methods associated with this object.
540f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                if (m_options.m_use_script_language)
541f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                {
542f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    // Special handling for one-liner specified inline.
543f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    if (m_options.m_use_one_liner)
544f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    {
545f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                        m_interpreter.GetScriptInterpreter()->SetWatchpointCommandCallback (wp_options,
546f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                                                                            m_options.m_one_liner.c_str());
547f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    }
548f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    // Special handling for using a Python function by name
549f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    // instead of extending the watchpoint callback data structures, we just automatize
550f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    // what the user would do manually: make their watchpoint command be a function call
551f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    else if (m_options.m_function_name.size())
552f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    {
553f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                        std::string oneliner(m_options.m_function_name);
554f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                        oneliner += "(frame, wp, internal_dict)";
555f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                        m_interpreter.GetScriptInterpreter()->SetWatchpointCommandCallback (wp_options,
556f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                                                                            oneliner.c_str());
557f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    }
558f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    else
559f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    {
560f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                        m_interpreter.GetScriptInterpreter()->CollectDataForWatchpointCommandCallback (wp_options,
561f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                                                                                       result);
562f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    }
563f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                }
564f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                else
565f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                {
566f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    // Special handling for one-liner specified inline.
567f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    if (m_options.m_use_one_liner)
568f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                        SetWatchpointCommandCallback (wp_options,
569f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                                      m_options.m_one_liner.c_str());
570f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    else
571f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                        CollectDataForWatchpointCommandCallback (wp_options,
572f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                                                 result);
573f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                }
574f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            }
575f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        }
576f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
577f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        return result.Succeeded();
578f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    }
579f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
580f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenprivate:
581f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    CommandOptions m_options;
582f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    static const char *g_reader_instructions;
583f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
584f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen};
585f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
586f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenconst char *
587f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenCommandObjectWatchpointCommandAdd::g_reader_instructions = "Enter your debugger command(s).  Type 'DONE' to end.";
588f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
589f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen// FIXME: "script-type" needs to have its contents determined dynamically, so somebody can add a new scripting
590f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen// language to lldb and have it pickable here without having to change this enumeration by hand and rebuild lldb proper.
591f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
592f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenstatic OptionEnumValueElement
593f3ec4617297810223deb545cb68214ca4dd8009cJohnny Cheng_script_option_enumeration[4] =
594f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen{
595f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    { eScriptLanguageNone,    "command",         "Commands are in the lldb command interpreter language"},
596f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    { eScriptLanguagePython,  "python",          "Commands are in the Python language."},
597f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    { eSortOrderByName,       "default-script",  "Commands are in the default scripting language."},
598f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    { 0,                      NULL,              NULL }
599f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen};
600f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
601f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenOptionDefinition
602f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenCommandObjectWatchpointCommandAdd::CommandOptions::g_option_table[] =
603f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen{
604560c51483461697b2f78c145d70d0cd285012c4dFilipe Cabecinhas    { LLDB_OPT_SET_1,   false, "one-liner",       'o', required_argument, NULL, 0, eArgTypeOneLiner,
605f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        "Specify a one-line watchpoint command inline. Be sure to surround it with quotes." },
606f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
607560c51483461697b2f78c145d70d0cd285012c4dFilipe Cabecinhas    { LLDB_OPT_SET_ALL, false, "stop-on-error",   'e', required_argument, NULL, 0, eArgTypeBoolean,
608f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        "Specify whether watchpoint command execution should terminate on error." },
609f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
610560c51483461697b2f78c145d70d0cd285012c4dFilipe Cabecinhas    { LLDB_OPT_SET_ALL, false, "script-type",     's', required_argument, g_script_option_enumeration, 0, eArgTypeNone,
611f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        "Specify the language for the commands - if none is specified, the lldb command interpreter will be used."},
612f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
613560c51483461697b2f78c145d70d0cd285012c4dFilipe Cabecinhas    { LLDB_OPT_SET_2,   false, "python-function", 'F', required_argument, NULL, 0, eArgTypePythonFunction,
614f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        "Give the name of a Python function to run as command for this watchpoint. Be sure to give a module name if appropriate."},
615f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
616f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
617f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen};
618f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
619f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen//-------------------------------------------------------------------------
620f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen// CommandObjectWatchpointCommandDelete
621f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen//-------------------------------------------------------------------------
622f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
623f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenclass CommandObjectWatchpointCommandDelete : public CommandObjectParsed
624f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen{
625f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenpublic:
626f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    CommandObjectWatchpointCommandDelete (CommandInterpreter &interpreter) :
627f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        CommandObjectParsed (interpreter,
628f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                             "delete",
629f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                             "Delete the set of commands from a watchpoint.",
630f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                             NULL)
631f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    {
632f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        CommandArgumentEntry arg;
633f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        CommandArgumentData wp_id_arg;
634f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
635f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        // Define the first (and only) variant of this arg.
636f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        wp_id_arg.arg_type = eArgTypeWatchpointID;
637f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        wp_id_arg.arg_repetition = eArgRepeatPlain;
638f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
639f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        // There is only one variant this argument could be; put it into the argument entry.
640f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        arg.push_back (wp_id_arg);
641f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
642f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        // Push the data for the first argument into the m_arguments vector.
643f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        m_arguments.push_back (arg);
644f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    }
645f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
646f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
647f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    virtual
648f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    ~CommandObjectWatchpointCommandDelete () {}
649f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
650f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenprotected:
651f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    virtual bool
652f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    DoExecute (Args& command, CommandReturnObject &result)
653f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    {
654f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
655f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
656f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        if (target == NULL)
657f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        {
658f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.AppendError ("There is not a current executable; there are no watchpoints from which to delete commands");
659f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.SetStatus (eReturnStatusFailed);
660f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            return false;
661f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        }
662f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
663f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        const WatchpointList &watchpoints = target->GetWatchpointList();
664f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        size_t num_watchpoints = watchpoints.GetSize();
665f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
666f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        if (num_watchpoints == 0)
667f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        {
668f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.AppendError ("No watchpoints exist to have commands deleted");
669f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.SetStatus (eReturnStatusFailed);
670f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            return false;
671f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        }
672f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
673f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        if (command.GetArgumentCount() == 0)
674f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        {
675f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.AppendError ("No watchpoint specified from which to delete the commands");
676f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.SetStatus (eReturnStatusFailed);
677f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            return false;
678f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        }
679f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
680f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        std::vector<uint32_t> valid_wp_ids;
681bf1bec6263157c86b5df7d6b19090571ed7885a3Jim Ingham        if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, valid_wp_ids))
682f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        {
683f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.AppendError("Invalid watchpoints specification.");
684f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.SetStatus(eReturnStatusFailed);
685f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            return false;
686f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        }
687f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
688f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        result.SetStatus(eReturnStatusSuccessFinishNoResult);
689f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        const size_t count = valid_wp_ids.size();
690f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        for (size_t i = 0; i < count; ++i)
691f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        {
692f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            uint32_t cur_wp_id = valid_wp_ids.at (i);
693f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            if (cur_wp_id != LLDB_INVALID_WATCH_ID)
694f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            {
695f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                Watchpoint *wp = target->GetWatchpointList().FindByID (cur_wp_id).get();
696f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                if (wp)
697f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    wp->ClearCallback();
698f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            }
699f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            else
700f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            {
701f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                result.AppendErrorWithFormat("Invalid watchpoint ID: %u.\n",
702f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                             cur_wp_id);
703f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                result.SetStatus (eReturnStatusFailed);
704f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                return false;
705f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            }
706f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        }
707f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        return result.Succeeded();
708f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    }
709f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen};
710f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
711f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen//-------------------------------------------------------------------------
712f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen// CommandObjectWatchpointCommandList
713f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen//-------------------------------------------------------------------------
714f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
715f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenclass CommandObjectWatchpointCommandList : public CommandObjectParsed
716f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen{
717f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenpublic:
718f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    CommandObjectWatchpointCommandList (CommandInterpreter &interpreter) :
719f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        CommandObjectParsed (interpreter,
720f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                             "list",
721f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                             "List the script or set of commands to be executed when the watchpoint is hit.",
722f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                              NULL)
723f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    {
724f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        CommandArgumentEntry arg;
725f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        CommandArgumentData wp_id_arg;
726f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
727f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        // Define the first (and only) variant of this arg.
728f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        wp_id_arg.arg_type = eArgTypeWatchpointID;
729f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        wp_id_arg.arg_repetition = eArgRepeatPlain;
730f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
731f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        // There is only one variant this argument could be; put it into the argument entry.
732f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        arg.push_back (wp_id_arg);
733f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
734f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        // Push the data for the first argument into the m_arguments vector.
735f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        m_arguments.push_back (arg);
736f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    }
737f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
738f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    virtual
739f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    ~CommandObjectWatchpointCommandList () {}
740f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
741f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chenprotected:
742f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    virtual bool
743f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    DoExecute (Args& command,
744f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen             CommandReturnObject &result)
745f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    {
746f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
747f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
748f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        if (target == NULL)
749f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        {
750f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.AppendError ("There is not a current executable; there are no watchpoints for which to list commands");
751f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.SetStatus (eReturnStatusFailed);
752f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            return false;
753f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        }
754f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
755f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        const WatchpointList &watchpoints = target->GetWatchpointList();
756f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        size_t num_watchpoints = watchpoints.GetSize();
757f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
758f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        if (num_watchpoints == 0)
759f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        {
760f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.AppendError ("No watchpoints exist for which to list commands");
761f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.SetStatus (eReturnStatusFailed);
762f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            return false;
763f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        }
764f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
765f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        if (command.GetArgumentCount() == 0)
766f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        {
767f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.AppendError ("No watchpoint specified for which to list the commands");
768f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.SetStatus (eReturnStatusFailed);
769f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            return false;
770f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        }
771f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
772f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        std::vector<uint32_t> valid_wp_ids;
773bf1bec6263157c86b5df7d6b19090571ed7885a3Jim Ingham        if (!CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs(target, command, valid_wp_ids))
774f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        {
775f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.AppendError("Invalid watchpoints specification.");
776f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            result.SetStatus(eReturnStatusFailed);
777f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            return false;
778f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        }
779f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
780f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        result.SetStatus(eReturnStatusSuccessFinishNoResult);
781f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        const size_t count = valid_wp_ids.size();
782f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        for (size_t i = 0; i < count; ++i)
783f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        {
784f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            uint32_t cur_wp_id = valid_wp_ids.at (i);
785f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            if (cur_wp_id != LLDB_INVALID_WATCH_ID)
786f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            {
787f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                Watchpoint *wp = target->GetWatchpointList().FindByID (cur_wp_id).get();
788f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
789f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                if (wp)
790f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                {
791f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    const WatchpointOptions *wp_options = wp->GetOptions();
792f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    if (wp_options)
793f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    {
794f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                        // Get the callback baton associated with the current watchpoint.
795f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                        const Baton *baton = wp_options->GetBaton();
796f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                        if (baton)
797f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                        {
798f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                            result.GetOutputStream().Printf ("Watchpoint %u:\n", cur_wp_id);
799f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                            result.GetOutputStream().IndentMore ();
800f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                            baton->GetDescription(&result.GetOutputStream(), eDescriptionLevelFull);
801f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                            result.GetOutputStream().IndentLess ();
802f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                        }
803f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                        else
804f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                        {
805f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                            result.AppendMessageWithFormat ("Watchpoint %u does not have an associated command.\n",
806f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                                                            cur_wp_id);
807f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                        }
808f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    }
809f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    result.SetStatus (eReturnStatusSuccessFinishResult);
810f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                }
811f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                else
812f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                {
813f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    result.AppendErrorWithFormat("Invalid watchpoint ID: %u.\n", cur_wp_id);
814f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                    result.SetStatus (eReturnStatusFailed);
815f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                }
816f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen            }
817f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        }
818f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
819f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen        return result.Succeeded();
820f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    }
821f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen};
822f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
823f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen//-------------------------------------------------------------------------
824f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen// CommandObjectWatchpointCommand
825f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen//-------------------------------------------------------------------------
826f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
827f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenCommandObjectWatchpointCommand::CommandObjectWatchpointCommand (CommandInterpreter &interpreter) :
828f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    CommandObjectMultiword (interpreter,
829f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                            "command",
830f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                            "A set of commands for adding, removing and examining bits of code to be executed when the watchpoint is hit (watchpoint 'commmands').",
831f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen                            "command <sub-command> [<sub-command-options>] <watchpoint-id>")
832f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen{
833f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    CommandObjectSP add_command_object (new CommandObjectWatchpointCommandAdd (interpreter));
834f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    CommandObjectSP delete_command_object (new CommandObjectWatchpointCommandDelete (interpreter));
835f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    CommandObjectSP list_command_object (new CommandObjectWatchpointCommandList (interpreter));
836f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
837f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    add_command_object->SetCommandName ("watchpoint command add");
838f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    delete_command_object->SetCommandName ("watchpoint command delete");
839f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen    list_command_object->SetCommandName ("watchpoint command list");
840f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
841d387b462eecb908af265ecc7006781b4532073adGreg Clayton    LoadSubCommand ("add",    add_command_object);
842d387b462eecb908af265ecc7006781b4532073adGreg Clayton    LoadSubCommand ("delete", delete_command_object);
843d387b462eecb908af265ecc7006781b4532073adGreg Clayton    LoadSubCommand ("list",   list_command_object);
844f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen}
845f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
846f3ec4617297810223deb545cb68214ca4dd8009cJohnny ChenCommandObjectWatchpointCommand::~CommandObjectWatchpointCommand ()
847f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen{
848f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen}
849f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
850f3ec4617297810223deb545cb68214ca4dd8009cJohnny Chen
851