1 /* MI Command Set - breakpoint and watchpoint commands.
2 Copyright (C) 2000-2013 Free Software Foundation, Inc.
3 Contributed by Cygnus Solutions (a Red Hat company).
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20 #include "defs.h"
21 #include "arch-utils.h"
22 #include "mi-cmds.h"
23 #include "ui-out.h"
24 #include "mi-out.h"
25 #include "breakpoint.h"
26 #include "gdb_string.h"
27 #include "mi-getopt.h"
28 #include "gdb.h"
29 #include "exceptions.h"
30 #include "observer.h"
31 #include "mi-main.h"
32 #include "mi-cmd-break.h"
33
34 enum
35 {
36 FROM_TTY = 0
37 };
38
39 /* True if MI breakpoint observers have been registered. */
40
41 static int mi_breakpoint_observers_installed;
42
43 /* Control whether breakpoint_notify may act. */
44
45 static int mi_can_breakpoint_notify;
46
47 /* Output a single breakpoint, when allowed. */
48
49 static void
breakpoint_notify(struct breakpoint * b)50 breakpoint_notify (struct breakpoint *b)
51 {
52 if (mi_can_breakpoint_notify)
53 gdb_breakpoint_query (current_uiout, b->number, NULL);
54 }
55
56 enum bp_type
57 {
58 REG_BP,
59 HW_BP,
60 REGEXP_BP
61 };
62
63 /* Arrange for all new breakpoints and catchpoints to be reported to
64 CURRENT_UIOUT until the cleanup returned by this function is run.
65
66 Note that MI output will be probably invalid if more than one
67 breakpoint is created inside one MI command. */
68
69 struct cleanup *
setup_breakpoint_reporting(void)70 setup_breakpoint_reporting (void)
71 {
72 struct cleanup *rev_flag;
73
74 if (! mi_breakpoint_observers_installed)
75 {
76 observer_attach_breakpoint_created (breakpoint_notify);
77 mi_breakpoint_observers_installed = 1;
78 }
79
80 rev_flag = make_cleanup_restore_integer (&mi_can_breakpoint_notify);
81 mi_can_breakpoint_notify = 1;
82
83 return rev_flag;
84 }
85
86
87 /* Implements the -break-insert command.
88 See the MI manual for the list of possible options. */
89
90 void
mi_cmd_break_insert(char * command,char ** argv,int argc)91 mi_cmd_break_insert (char *command, char **argv, int argc)
92 {
93 char *address = NULL;
94 int hardware = 0;
95 int temp_p = 0;
96 int thread = -1;
97 int ignore_count = 0;
98 char *condition = NULL;
99 int pending = 0;
100 int enabled = 1;
101 int tracepoint = 0;
102 struct cleanup *back_to;
103 enum bptype type_wanted;
104 struct breakpoint_ops *ops;
105
106 enum opt
107 {
108 HARDWARE_OPT, TEMP_OPT, CONDITION_OPT,
109 IGNORE_COUNT_OPT, THREAD_OPT, PENDING_OPT, DISABLE_OPT,
110 TRACEPOINT_OPT,
111 };
112 static const struct mi_opt opts[] =
113 {
114 {"h", HARDWARE_OPT, 0},
115 {"t", TEMP_OPT, 0},
116 {"c", CONDITION_OPT, 1},
117 {"i", IGNORE_COUNT_OPT, 1},
118 {"p", THREAD_OPT, 1},
119 {"f", PENDING_OPT, 0},
120 {"d", DISABLE_OPT, 0},
121 {"a", TRACEPOINT_OPT, 0},
122 { 0, 0, 0 }
123 };
124
125 /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
126 to denote the end of the option list. */
127 int oind = 0;
128 char *oarg;
129
130 while (1)
131 {
132 int opt = mi_getopt ("-break-insert", argc, argv,
133 opts, &oind, &oarg);
134 if (opt < 0)
135 break;
136 switch ((enum opt) opt)
137 {
138 case TEMP_OPT:
139 temp_p = 1;
140 break;
141 case HARDWARE_OPT:
142 hardware = 1;
143 break;
144 case CONDITION_OPT:
145 condition = oarg;
146 break;
147 case IGNORE_COUNT_OPT:
148 ignore_count = atol (oarg);
149 break;
150 case THREAD_OPT:
151 thread = atol (oarg);
152 break;
153 case PENDING_OPT:
154 pending = 1;
155 break;
156 case DISABLE_OPT:
157 enabled = 0;
158 break;
159 case TRACEPOINT_OPT:
160 tracepoint = 1;
161 break;
162 }
163 }
164
165 if (oind >= argc)
166 error (_("-break-insert: Missing <location>"));
167 if (oind < argc - 1)
168 error (_("-break-insert: Garbage following <location>"));
169 address = argv[oind];
170
171 /* Now we have what we need, let's insert the breakpoint! */
172 back_to = setup_breakpoint_reporting ();
173
174 /* Note that to request a fast tracepoint, the client uses the
175 "hardware" flag, although there's nothing of hardware related to
176 fast tracepoints -- one can implement slow tracepoints with
177 hardware breakpoints, but fast tracepoints are always software.
178 "fast" is a misnomer, actually, "jump" would be more appropriate.
179 A simulator or an emulator could conceivably implement fast
180 regular non-jump based tracepoints. */
181 type_wanted = (tracepoint
182 ? (hardware ? bp_fast_tracepoint : bp_tracepoint)
183 : (hardware ? bp_hardware_breakpoint : bp_breakpoint));
184 ops = tracepoint ? &tracepoint_breakpoint_ops : &bkpt_breakpoint_ops;
185
186 create_breakpoint (get_current_arch (), address, condition, thread,
187 NULL,
188 0 /* condition and thread are valid. */,
189 temp_p, type_wanted,
190 ignore_count,
191 pending ? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE,
192 ops, 0, enabled, 0, 0);
193 do_cleanups (back_to);
194
195 }
196
197 enum wp_type
198 {
199 REG_WP,
200 READ_WP,
201 ACCESS_WP
202 };
203
204 void
mi_cmd_break_passcount(char * command,char ** argv,int argc)205 mi_cmd_break_passcount (char *command, char **argv, int argc)
206 {
207 int n;
208 int p;
209 struct tracepoint *t;
210
211 if (argc != 2)
212 error (_("Usage: tracepoint-number passcount"));
213
214 n = atoi (argv[0]);
215 p = atoi (argv[1]);
216 t = get_tracepoint (n);
217
218 if (t)
219 {
220 t->pass_count = p;
221 observer_notify_breakpoint_modified (&t->base);
222 }
223 else
224 {
225 error (_("Could not find tracepoint %d"), n);
226 }
227 }
228
229 /* Insert a watchpoint. The type of watchpoint is specified by the
230 first argument:
231 -break-watch <expr> --> insert a regular wp.
232 -break-watch -r <expr> --> insert a read watchpoint.
233 -break-watch -a <expr> --> insert an access wp. */
234
235 void
mi_cmd_break_watch(char * command,char ** argv,int argc)236 mi_cmd_break_watch (char *command, char **argv, int argc)
237 {
238 char *expr = NULL;
239 enum wp_type type = REG_WP;
240 enum opt
241 {
242 READ_OPT, ACCESS_OPT
243 };
244 static const struct mi_opt opts[] =
245 {
246 {"r", READ_OPT, 0},
247 {"a", ACCESS_OPT, 0},
248 { 0, 0, 0 }
249 };
250
251 /* Parse arguments. */
252 int oind = 0;
253 char *oarg;
254
255 while (1)
256 {
257 int opt = mi_getopt ("-break-watch", argc, argv,
258 opts, &oind, &oarg);
259
260 if (opt < 0)
261 break;
262 switch ((enum opt) opt)
263 {
264 case READ_OPT:
265 type = READ_WP;
266 break;
267 case ACCESS_OPT:
268 type = ACCESS_WP;
269 break;
270 }
271 }
272 if (oind >= argc)
273 error (_("-break-watch: Missing <expression>"));
274 if (oind < argc - 1)
275 error (_("-break-watch: Garbage following <expression>"));
276 expr = argv[oind];
277
278 /* Now we have what we need, let's insert the watchpoint! */
279 switch (type)
280 {
281 case REG_WP:
282 watch_command_wrapper (expr, FROM_TTY, 0);
283 break;
284 case READ_WP:
285 rwatch_command_wrapper (expr, FROM_TTY, 0);
286 break;
287 case ACCESS_WP:
288 awatch_command_wrapper (expr, FROM_TTY, 0);
289 break;
290 default:
291 error (_("-break-watch: Unknown watchpoint type."));
292 }
293 }
294
295 /* The mi_read_next_line consults these variable to return successive
296 command lines. While it would be clearer to use a closure pointer,
297 it is not expected that any future code will use read_command_lines_1,
298 therefore no point of overengineering. */
299
300 static char **mi_command_line_array;
301 static int mi_command_line_array_cnt;
302 static int mi_command_line_array_ptr;
303
304 static char *
mi_read_next_line(void)305 mi_read_next_line (void)
306 {
307 if (mi_command_line_array_ptr == mi_command_line_array_cnt)
308 return NULL;
309 else
310 return mi_command_line_array[mi_command_line_array_ptr++];
311 }
312
313 void
mi_cmd_break_commands(char * command,char ** argv,int argc)314 mi_cmd_break_commands (char *command, char **argv, int argc)
315 {
316 struct command_line *break_command;
317 char *endptr;
318 int bnum;
319 struct breakpoint *b;
320
321 if (argc < 1)
322 error (_("USAGE: %s <BKPT> [<COMMAND> [<COMMAND>...]]"), command);
323
324 bnum = strtol (argv[0], &endptr, 0);
325 if (endptr == argv[0])
326 error (_("breakpoint number argument \"%s\" is not a number."),
327 argv[0]);
328 else if (*endptr != '\0')
329 error (_("junk at the end of breakpoint number argument \"%s\"."),
330 argv[0]);
331
332 b = get_breakpoint (bnum);
333 if (b == NULL)
334 error (_("breakpoint %d not found."), bnum);
335
336 mi_command_line_array = argv;
337 mi_command_line_array_ptr = 1;
338 mi_command_line_array_cnt = argc;
339
340 if (is_tracepoint (b))
341 break_command = read_command_lines_1 (mi_read_next_line, 1,
342 check_tracepoint_command, b);
343 else
344 break_command = read_command_lines_1 (mi_read_next_line, 1, 0, 0);
345
346 breakpoint_set_commands (b, break_command);
347 }
348
349