Mass rename `explicit' -> `explicit_loc'.
[deliverable/binutils-gdb.git] / gdb / mi / mi-cmd-break.c
1 /* MI Command Set - breakpoint and watchpoint commands.
2 Copyright (C) 2000-2015 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 "mi-getopt.h"
27 #include "gdb.h"
28 #include "observer.h"
29 #include "mi-main.h"
30 #include "mi-cmd-break.h"
31 #include "language.h"
32 #include "location.h"
33 #include "linespec.h"
34 #include "gdb_obstack.h"
35 #include <ctype.h>
36
37 enum
38 {
39 FROM_TTY = 0
40 };
41
42 /* True if MI breakpoint observers have been registered. */
43
44 static int mi_breakpoint_observers_installed;
45
46 /* Control whether breakpoint_notify may act. */
47
48 static int mi_can_breakpoint_notify;
49
50 /* Output a single breakpoint, when allowed. */
51
52 static void
53 breakpoint_notify (struct breakpoint *b)
54 {
55 if (mi_can_breakpoint_notify)
56 gdb_breakpoint_query (current_uiout, b->number, NULL);
57 }
58
59 enum bp_type
60 {
61 REG_BP,
62 HW_BP,
63 REGEXP_BP
64 };
65
66 /* Arrange for all new breakpoints and catchpoints to be reported to
67 CURRENT_UIOUT until the cleanup returned by this function is run.
68
69 Note that MI output will be probably invalid if more than one
70 breakpoint is created inside one MI command. */
71
72 struct cleanup *
73 setup_breakpoint_reporting (void)
74 {
75 struct cleanup *rev_flag;
76
77 if (! mi_breakpoint_observers_installed)
78 {
79 observer_attach_breakpoint_created (breakpoint_notify);
80 mi_breakpoint_observers_installed = 1;
81 }
82
83 rev_flag = make_cleanup_restore_integer (&mi_can_breakpoint_notify);
84 mi_can_breakpoint_notify = 1;
85
86 return rev_flag;
87 }
88
89
90 /* Convert arguments in ARGV to the string in "format",argv,argv...
91 and return it. */
92
93 static char *
94 mi_argv_to_format (char **argv, int argc)
95 {
96 int i;
97 struct obstack obstack;
98 char *ret;
99
100 obstack_init (&obstack);
101
102 /* Convert ARGV[OIND + 1] to format string and save to FORMAT. */
103 obstack_1grow (&obstack, '\"');
104 for (i = 0; i < strlen (argv[0]); i++)
105 {
106 switch (argv[0][i])
107 {
108 case '\\':
109 obstack_grow (&obstack, "\\\\", 2);
110 break;
111 case '\a':
112 obstack_grow (&obstack, "\\a", 2);
113 break;
114 case '\b':
115 obstack_grow (&obstack, "\\b", 2);
116 break;
117 case '\f':
118 obstack_grow (&obstack, "\\f", 2);
119 break;
120 case '\n':
121 obstack_grow (&obstack, "\\n", 2);
122 break;
123 case '\r':
124 obstack_grow (&obstack, "\\r", 2);
125 break;
126 case '\t':
127 obstack_grow (&obstack, "\\t", 2);
128 break;
129 case '\v':
130 obstack_grow (&obstack, "\\v", 2);
131 break;
132 case '"':
133 obstack_grow (&obstack, "\\\"", 2);
134 break;
135 default:
136 if (isprint (argv[0][i]))
137 obstack_grow (&obstack, argv[0] + i, 1);
138 else
139 {
140 char tmp[5];
141
142 xsnprintf (tmp, sizeof (tmp), "\\%o",
143 (unsigned char) argv[0][i]);
144 obstack_grow (&obstack, tmp, strlen (tmp));
145 }
146 break;
147 }
148 }
149 obstack_1grow (&obstack, '\"');
150
151 /* Apply other argv to FORMAT. */
152 for (i = 1; i < argc; i++)
153 {
154 obstack_1grow (&obstack, ',');
155 obstack_grow (&obstack, argv[i], strlen (argv[i]));
156 }
157 obstack_1grow (&obstack, '\0');
158
159 ret = xstrdup (obstack_finish (&obstack));
160 obstack_free (&obstack, NULL);
161
162 return ret;
163 }
164
165 /* Insert breakpoint.
166 If dprintf is true, it will insert dprintf.
167 If not, it will insert other type breakpoint. */
168
169 static void
170 mi_cmd_break_insert_1 (int dprintf, char *command, char **argv, int argc)
171 {
172 char *address = NULL;
173 int hardware = 0;
174 int temp_p = 0;
175 int thread = -1;
176 int ignore_count = 0;
177 char *condition = NULL;
178 int pending = 0;
179 int enabled = 1;
180 int tracepoint = 0;
181 struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
182 enum bptype type_wanted;
183 struct event_location *location;
184 struct breakpoint_ops *ops;
185 int is_explicit = 0;
186 struct explicit_location explicit_loc;
187 char *extra_string = NULL;
188
189 enum opt
190 {
191 HARDWARE_OPT, TEMP_OPT, CONDITION_OPT,
192 IGNORE_COUNT_OPT, THREAD_OPT, PENDING_OPT, DISABLE_OPT,
193 TRACEPOINT_OPT,
194 EXPLICIT_SOURCE_OPT, EXPLICIT_FUNC_OPT,
195 EXPLICIT_LABEL_OPT, EXPLICIT_LINE_OPT
196 };
197 static const struct mi_opt opts[] =
198 {
199 {"h", HARDWARE_OPT, 0},
200 {"t", TEMP_OPT, 0},
201 {"c", CONDITION_OPT, 1},
202 {"i", IGNORE_COUNT_OPT, 1},
203 {"p", THREAD_OPT, 1},
204 {"f", PENDING_OPT, 0},
205 {"d", DISABLE_OPT, 0},
206 {"a", TRACEPOINT_OPT, 0},
207 {"-source" , EXPLICIT_SOURCE_OPT, 1},
208 {"-function", EXPLICIT_FUNC_OPT, 1},
209 {"-label", EXPLICIT_LABEL_OPT, 1},
210 {"-line", EXPLICIT_LINE_OPT, 1},
211 { 0, 0, 0 }
212 };
213
214 /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
215 to denote the end of the option list. */
216 int oind = 0;
217 char *oarg;
218
219 initialize_explicit_location (&explicit_loc);
220
221 while (1)
222 {
223 int opt = mi_getopt ("-break-insert", argc, argv,
224 opts, &oind, &oarg);
225 if (opt < 0)
226 break;
227 switch ((enum opt) opt)
228 {
229 case TEMP_OPT:
230 temp_p = 1;
231 break;
232 case HARDWARE_OPT:
233 hardware = 1;
234 break;
235 case CONDITION_OPT:
236 condition = oarg;
237 break;
238 case IGNORE_COUNT_OPT:
239 ignore_count = atol (oarg);
240 break;
241 case THREAD_OPT:
242 thread = atol (oarg);
243 break;
244 case PENDING_OPT:
245 pending = 1;
246 break;
247 case DISABLE_OPT:
248 enabled = 0;
249 break;
250 case TRACEPOINT_OPT:
251 tracepoint = 1;
252 break;
253 case EXPLICIT_SOURCE_OPT:
254 is_explicit = 1;
255 explicit_loc.source_filename = oarg;
256 break;
257 case EXPLICIT_FUNC_OPT:
258 is_explicit = 1;
259 explicit_loc.function_name = oarg;
260 break;
261 case EXPLICIT_LABEL_OPT:
262 is_explicit = 1;
263 explicit_loc.label_name = oarg;
264 break;
265 case EXPLICIT_LINE_OPT:
266 is_explicit = 1;
267 explicit_loc.line_offset = linespec_parse_line_offset (oarg);
268 break;
269 }
270 }
271
272 if (oind >= argc && !is_explicit)
273 error (_("-%s-insert: Missing <location>"),
274 dprintf ? "dprintf" : "break");
275 if (dprintf)
276 {
277 int format_num = is_explicit ? oind : oind + 1;
278
279 if (hardware || tracepoint)
280 error (_("-dprintf-insert: does not support -h or -a"));
281 if (format_num >= argc)
282 error (_("-dprintf-insert: Missing <format>"));
283
284 extra_string = mi_argv_to_format (argv + format_num, argc - format_num);
285 make_cleanup (xfree, extra_string);
286 address = argv[oind];
287 }
288 else
289 {
290 if (is_explicit)
291 {
292 if (oind < argc)
293 error (_("-break-insert: Garbage following explicit location"));
294 }
295 else
296 {
297 if (oind < argc - 1)
298 error (_("-break-insert: Garbage following <location>"));
299 address = argv[oind];
300 }
301 }
302
303 /* Now we have what we need, let's insert the breakpoint! */
304 setup_breakpoint_reporting ();
305
306 if (tracepoint)
307 {
308 /* Note that to request a fast tracepoint, the client uses the
309 "hardware" flag, although there's nothing of hardware related to
310 fast tracepoints -- one can implement slow tracepoints with
311 hardware breakpoints, but fast tracepoints are always software.
312 "fast" is a misnomer, actually, "jump" would be more appropriate.
313 A simulator or an emulator could conceivably implement fast
314 regular non-jump based tracepoints. */
315 type_wanted = hardware ? bp_fast_tracepoint : bp_tracepoint;
316 ops = &tracepoint_breakpoint_ops;
317 }
318 else if (dprintf)
319 {
320 type_wanted = bp_dprintf;
321 ops = &dprintf_breakpoint_ops;
322 }
323 else
324 {
325 type_wanted = hardware ? bp_hardware_breakpoint : bp_breakpoint;
326 ops = &bkpt_breakpoint_ops;
327 }
328
329 if (is_explicit)
330 {
331 /* Error check -- we must have one of the other
332 parameters specified. */
333 if (explicit_loc.source_filename != NULL
334 && explicit_loc.function_name == NULL
335 && explicit_loc.label_name == NULL
336 && explicit_loc.line_offset.sign == LINE_OFFSET_UNKNOWN)
337 error (_("-%s-insert: --source option requires --function, --label,"
338 " or --line"), dprintf ? "dprintf" : "break");
339
340 location = new_explicit_location (&explicit_loc);
341 }
342 else
343 {
344 location = string_to_event_location (&address, current_language);
345 if (*address)
346 {
347 delete_event_location (location);
348 error (_("Garbage '%s' at end of location"), address);
349 }
350 }
351
352 make_cleanup_delete_event_location (location);
353
354 create_breakpoint (get_current_arch (), location, condition, thread,
355 extra_string,
356 0 /* condition and thread are valid. */,
357 temp_p, type_wanted,
358 ignore_count,
359 pending ? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE,
360 ops, 0, enabled, 0, 0);
361 do_cleanups (back_to);
362 }
363
364 /* Implements the -break-insert command.
365 See the MI manual for the list of possible options. */
366
367 void
368 mi_cmd_break_insert (char *command, char **argv, int argc)
369 {
370 mi_cmd_break_insert_1 (0, command, argv, argc);
371 }
372
373 /* Implements the -dprintf-insert command.
374 See the MI manual for the list of possible options. */
375
376 void
377 mi_cmd_dprintf_insert (char *command, char **argv, int argc)
378 {
379 mi_cmd_break_insert_1 (1, command, argv, argc);
380 }
381
382 enum wp_type
383 {
384 REG_WP,
385 READ_WP,
386 ACCESS_WP
387 };
388
389 void
390 mi_cmd_break_passcount (char *command, char **argv, int argc)
391 {
392 int n;
393 int p;
394 struct tracepoint *t;
395
396 if (argc != 2)
397 error (_("Usage: tracepoint-number passcount"));
398
399 n = atoi (argv[0]);
400 p = atoi (argv[1]);
401 t = get_tracepoint (n);
402
403 if (t)
404 {
405 t->pass_count = p;
406 observer_notify_breakpoint_modified (&t->base);
407 }
408 else
409 {
410 error (_("Could not find tracepoint %d"), n);
411 }
412 }
413
414 /* Insert a watchpoint. The type of watchpoint is specified by the
415 first argument:
416 -break-watch <expr> --> insert a regular wp.
417 -break-watch -r <expr> --> insert a read watchpoint.
418 -break-watch -a <expr> --> insert an access wp. */
419
420 void
421 mi_cmd_break_watch (char *command, char **argv, int argc)
422 {
423 char *expr = NULL;
424 enum wp_type type = REG_WP;
425 enum opt
426 {
427 READ_OPT, ACCESS_OPT
428 };
429 static const struct mi_opt opts[] =
430 {
431 {"r", READ_OPT, 0},
432 {"a", ACCESS_OPT, 0},
433 { 0, 0, 0 }
434 };
435
436 /* Parse arguments. */
437 int oind = 0;
438 char *oarg;
439
440 while (1)
441 {
442 int opt = mi_getopt ("-break-watch", argc, argv,
443 opts, &oind, &oarg);
444
445 if (opt < 0)
446 break;
447 switch ((enum opt) opt)
448 {
449 case READ_OPT:
450 type = READ_WP;
451 break;
452 case ACCESS_OPT:
453 type = ACCESS_WP;
454 break;
455 }
456 }
457 if (oind >= argc)
458 error (_("-break-watch: Missing <expression>"));
459 if (oind < argc - 1)
460 error (_("-break-watch: Garbage following <expression>"));
461 expr = argv[oind];
462
463 /* Now we have what we need, let's insert the watchpoint! */
464 switch (type)
465 {
466 case REG_WP:
467 watch_command_wrapper (expr, FROM_TTY, 0);
468 break;
469 case READ_WP:
470 rwatch_command_wrapper (expr, FROM_TTY, 0);
471 break;
472 case ACCESS_WP:
473 awatch_command_wrapper (expr, FROM_TTY, 0);
474 break;
475 default:
476 error (_("-break-watch: Unknown watchpoint type."));
477 }
478 }
479
480 /* The mi_read_next_line consults these variable to return successive
481 command lines. While it would be clearer to use a closure pointer,
482 it is not expected that any future code will use read_command_lines_1,
483 therefore no point of overengineering. */
484
485 static char **mi_command_line_array;
486 static int mi_command_line_array_cnt;
487 static int mi_command_line_array_ptr;
488
489 static char *
490 mi_read_next_line (void)
491 {
492 if (mi_command_line_array_ptr == mi_command_line_array_cnt)
493 return NULL;
494 else
495 return mi_command_line_array[mi_command_line_array_ptr++];
496 }
497
498 void
499 mi_cmd_break_commands (char *command, char **argv, int argc)
500 {
501 struct command_line *break_command;
502 char *endptr;
503 int bnum;
504 struct breakpoint *b;
505
506 if (argc < 1)
507 error (_("USAGE: %s <BKPT> [<COMMAND> [<COMMAND>...]]"), command);
508
509 bnum = strtol (argv[0], &endptr, 0);
510 if (endptr == argv[0])
511 error (_("breakpoint number argument \"%s\" is not a number."),
512 argv[0]);
513 else if (*endptr != '\0')
514 error (_("junk at the end of breakpoint number argument \"%s\"."),
515 argv[0]);
516
517 b = get_breakpoint (bnum);
518 if (b == NULL)
519 error (_("breakpoint %d not found."), bnum);
520
521 mi_command_line_array = argv;
522 mi_command_line_array_ptr = 1;
523 mi_command_line_array_cnt = argc;
524
525 if (is_tracepoint (b))
526 break_command = read_command_lines_1 (mi_read_next_line, 1,
527 check_tracepoint_command, b);
528 else
529 break_command = read_command_lines_1 (mi_read_next_line, 1, 0, 0);
530
531 breakpoint_set_commands (b, break_command);
532 }
533
This page took 0.04143 seconds and 4 git commands to generate.