]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/mi/mi-cmd-break.c
GDB copyright headers update after running GDB's copyright.py script.
[thirdparty/binutils-gdb.git] / gdb / mi / mi-cmd-break.c
CommitLineData
fb40c209 1/* MI Command Set - breakpoint and watchpoint commands.
618f726f 2 Copyright (C) 2000-2016 Free Software Foundation, Inc.
ab91fdd5 3 Contributed by Cygnus Solutions (a Red Hat company).
fb40c209
AC
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
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
fb40c209
AC
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
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
fb40c209
AC
19
20#include "defs.h"
a6d9a66e 21#include "arch-utils.h"
fb40c209
AC
22#include "mi-cmds.h"
23#include "ui-out.h"
24#include "mi-out.h"
25#include "breakpoint.h"
fb40c209 26#include "mi-getopt.h"
5b7f31a4 27#include "gdb.h"
383f836e 28#include "observer.h"
8d3788bd 29#include "mi-main.h"
91985142 30#include "mi-cmd-break.h"
f00aae0f
KS
31#include "language.h"
32#include "location.h"
33#include "linespec.h"
c5867ab6
HZ
34#include "gdb_obstack.h"
35#include <ctype.h>
fb40c209 36
fb40c209
AC
37enum
38 {
39 FROM_TTY = 0
40 };
41
383f836e
TT
42/* True if MI breakpoint observers have been registered. */
43
44static int mi_breakpoint_observers_installed;
45
46/* Control whether breakpoint_notify may act. */
47
48static int mi_can_breakpoint_notify;
49
2b03b41d 50/* Output a single breakpoint, when allowed. */
fb40c209
AC
51
52static void
8d3788bd 53breakpoint_notify (struct breakpoint *b)
fb40c209 54{
383f836e 55 if (mi_can_breakpoint_notify)
79a45e25 56 gdb_breakpoint_query (current_uiout, b->number, NULL);
fb40c209
AC
57}
58
fb40c209
AC
59enum bp_type
60 {
61 REG_BP,
62 HW_BP,
63 REGEXP_BP
64 };
65
91985142
MG
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
72struct cleanup *
73setup_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
c5867ab6
HZ
90/* Convert arguments in ARGV to the string in "format",argv,argv...
91 and return it. */
fb40c209 92
c5867ab6
HZ
93static char *
94mi_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;
fa876972
HZ
132 case '"':
133 obstack_grow (&obstack, "\\\"", 2);
134 break;
c5867ab6
HZ
135 default:
136 if (isprint (argv[0][i]))
137 obstack_grow (&obstack, argv[0] + i, 1);
138 else
139 {
140 char tmp[5];
141
ce70887a
JB
142 xsnprintf (tmp, sizeof (tmp), "\\%o",
143 (unsigned char) argv[0][i]);
c5867ab6
HZ
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
224c3ddb 159 ret = xstrdup ((const char *) obstack_finish (&obstack));
c5867ab6
HZ
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
169static void
170mi_cmd_break_insert_1 (int dprintf, char *command, char **argv, int argc)
fb40c209
AC
171{
172 char *address = NULL;
8cdf0e15 173 int hardware = 0;
fb40c209
AC
174 int temp_p = 0;
175 int thread = -1;
176 int ignore_count = 0;
177 char *condition = NULL;
afe8ab22 178 int pending = 0;
41447f92 179 int enabled = 1;
6534d786 180 int tracepoint = 0;
c5867ab6 181 struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
0fb4aa4b 182 enum bptype type_wanted;
f00aae0f 183 struct event_location *location;
19ca11c5 184 struct breakpoint_ops *ops;
eb8c4e2e 185 int is_explicit = 0;
67994074 186 struct explicit_location explicit_loc;
c5867ab6 187 char *extra_string = NULL;
41447f92 188
fb40c209
AC
189 enum opt
190 {
8cdf0e15 191 HARDWARE_OPT, TEMP_OPT, CONDITION_OPT,
6534d786
VP
192 IGNORE_COUNT_OPT, THREAD_OPT, PENDING_OPT, DISABLE_OPT,
193 TRACEPOINT_OPT,
eb8c4e2e
KS
194 EXPLICIT_SOURCE_OPT, EXPLICIT_FUNC_OPT,
195 EXPLICIT_LABEL_OPT, EXPLICIT_LINE_OPT
fb40c209 196 };
91174723 197 static const struct mi_opt opts[] =
fb40c209
AC
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},
afe8ab22 204 {"f", PENDING_OPT, 0},
41447f92 205 {"d", DISABLE_OPT, 0},
6534d786 206 {"a", TRACEPOINT_OPT, 0},
eb8c4e2e
KS
207 {"-source" , EXPLICIT_SOURCE_OPT, 1},
208 {"-function", EXPLICIT_FUNC_OPT, 1},
209 {"-label", EXPLICIT_LABEL_OPT, 1},
210 {"-line", EXPLICIT_LINE_OPT, 1},
d5d6fca5 211 { 0, 0, 0 }
fb40c209
AC
212 };
213
214 /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
215 to denote the end of the option list. */
f8c000a2
AS
216 int oind = 0;
217 char *oarg;
102040f0 218
67994074 219 initialize_explicit_location (&explicit_loc);
eb8c4e2e 220
fb40c209
AC
221 while (1)
222 {
1b05df00 223 int opt = mi_getopt ("-break-insert", argc, argv,
f8c000a2 224 opts, &oind, &oarg);
fb40c209
AC
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:
8cdf0e15 233 hardware = 1;
fb40c209 234 break;
fb40c209 235 case CONDITION_OPT:
f8c000a2 236 condition = oarg;
fb40c209
AC
237 break;
238 case IGNORE_COUNT_OPT:
f8c000a2 239 ignore_count = atol (oarg);
fb40c209
AC
240 break;
241 case THREAD_OPT:
f8c000a2 242 thread = atol (oarg);
fb40c209 243 break;
afe8ab22
VP
244 case PENDING_OPT:
245 pending = 1;
246 break;
41447f92
VP
247 case DISABLE_OPT:
248 enabled = 0;
6534d786
VP
249 break;
250 case TRACEPOINT_OPT:
251 tracepoint = 1;
252 break;
eb8c4e2e
KS
253 case EXPLICIT_SOURCE_OPT:
254 is_explicit = 1;
67994074 255 explicit_loc.source_filename = oarg;
eb8c4e2e
KS
256 break;
257 case EXPLICIT_FUNC_OPT:
258 is_explicit = 1;
67994074 259 explicit_loc.function_name = oarg;
eb8c4e2e
KS
260 break;
261 case EXPLICIT_LABEL_OPT:
262 is_explicit = 1;
67994074 263 explicit_loc.label_name = oarg;
eb8c4e2e
KS
264 break;
265 case EXPLICIT_LINE_OPT:
266 is_explicit = 1;
67994074 267 explicit_loc.line_offset = linespec_parse_line_offset (oarg);
eb8c4e2e 268 break;
fb40c209
AC
269 }
270 }
271
eb8c4e2e 272 if (oind >= argc && !is_explicit)
c5867ab6
HZ
273 error (_("-%s-insert: Missing <location>"),
274 dprintf ? "dprintf" : "break");
c5867ab6
HZ
275 if (dprintf)
276 {
eb8c4e2e 277 int format_num = is_explicit ? oind : oind + 1;
c5867ab6
HZ
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);
eb8c4e2e 286 address = argv[oind];
c5867ab6
HZ
287 }
288 else
289 {
eb8c4e2e
KS
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 }
c5867ab6 301 }
fb40c209 302
2b03b41d 303 /* Now we have what we need, let's insert the breakpoint! */
c5867ab6
HZ
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 }
0fb4aa4b 328
eb8c4e2e
KS
329 if (is_explicit)
330 {
331 /* Error check -- we must have one of the other
332 parameters specified. */
67994074
KS
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)
eb8c4e2e
KS
337 error (_("-%s-insert: --source option requires --function, --label,"
338 " or --line"), dprintf ? "dprintf" : "break");
339
67994074 340 location = new_explicit_location (&explicit_loc);
eb8c4e2e
KS
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 }
f00aae0f 351
eb8c4e2e 352 make_cleanup_delete_event_location (location);
f00aae0f
KS
353
354 create_breakpoint (get_current_arch (), location, condition, thread,
c5867ab6 355 extra_string,
8cdf0e15 356 0 /* condition and thread are valid. */,
0fb4aa4b 357 temp_p, type_wanted,
8cdf0e15
VP
358 ignore_count,
359 pending ? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE,
19ca11c5 360 ops, 0, enabled, 0, 0);
8cdf0e15 361 do_cleanups (back_to);
c5867ab6
HZ
362}
363
364/* Implements the -break-insert command.
365 See the MI manual for the list of possible options. */
8cdf0e15 366
c5867ab6
HZ
367void
368mi_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
376void
377mi_cmd_dprintf_insert (char *command, char **argv, int argc)
378{
379 mi_cmd_break_insert_1 (1, command, argv, argc);
fb40c209
AC
380}
381
382enum wp_type
383{
384 REG_WP,
385 READ_WP,
386 ACCESS_WP
387};
388
9b4c786c
VP
389void
390mi_cmd_break_passcount (char *command, char **argv, int argc)
391{
392 int n;
393 int p;
d9b3f62e 394 struct tracepoint *t;
9b4c786c
VP
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;
6f6484cd 406 observer_notify_breakpoint_modified (&t->base);
9b4c786c
VP
407 }
408 else
409 {
401a70b8 410 error (_("Could not find tracepoint %d"), n);
9b4c786c
VP
411 }
412}
413
fb40c209
AC
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.
2b03b41d 418 -break-watch -a <expr> --> insert an access wp. */
fb40c209 419
ce8f13f8 420void
fb40c209
AC
421mi_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 };
91174723 429 static const struct mi_opt opts[] =
fb40c209
AC
430 {
431 {"r", READ_OPT, 0},
432 {"a", ACCESS_OPT, 0},
d5d6fca5 433 { 0, 0, 0 }
fb40c209
AC
434 };
435
436 /* Parse arguments. */
f8c000a2
AS
437 int oind = 0;
438 char *oarg;
102040f0 439
fb40c209
AC
440 while (1)
441 {
1b05df00 442 int opt = mi_getopt ("-break-watch", argc, argv,
f8c000a2 443 opts, &oind, &oarg);
102040f0 444
fb40c209
AC
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 }
f8c000a2 457 if (oind >= argc)
1b05df00 458 error (_("-break-watch: Missing <expression>"));
f8c000a2 459 if (oind < argc - 1)
1b05df00 460 error (_("-break-watch: Garbage following <expression>"));
f8c000a2 461 expr = argv[oind];
fb40c209 462
2b03b41d 463 /* Now we have what we need, let's insert the watchpoint! */
fb40c209
AC
464 switch (type)
465 {
466 case REG_WP:
84f4c1fe 467 watch_command_wrapper (expr, FROM_TTY, 0);
fb40c209
AC
468 break;
469 case READ_WP:
84f4c1fe 470 rwatch_command_wrapper (expr, FROM_TTY, 0);
fb40c209
AC
471 break;
472 case ACCESS_WP:
84f4c1fe 473 awatch_command_wrapper (expr, FROM_TTY, 0);
fb40c209
AC
474 break;
475 default:
1b05df00 476 error (_("-break-watch: Unknown watchpoint type."));
fb40c209 477 }
fb40c209 478}
48cb2d85
VP
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
485static char **mi_command_line_array;
486static int mi_command_line_array_cnt;
487static int mi_command_line_array_ptr;
488
489static char *
a58d7472 490mi_read_next_line (void)
48cb2d85
VP
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
498void
499mi_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)
9b20d036 507 error (_("USAGE: %s <BKPT> [<COMMAND> [<COMMAND>...]]"), command);
48cb2d85
VP
508
509 bnum = strtol (argv[0], &endptr, 0);
510 if (endptr == argv[0])
9b20d036 511 error (_("breakpoint number argument \"%s\" is not a number."),
48cb2d85
VP
512 argv[0]);
513 else if (*endptr != '\0')
9b20d036 514 error (_("junk at the end of breakpoint number argument \"%s\"."),
48cb2d85
VP
515 argv[0]);
516
517 b = get_breakpoint (bnum);
518 if (b == NULL)
9b20d036 519 error (_("breakpoint %d not found."), bnum);
48cb2d85
VP
520
521 mi_command_line_array = argv;
522 mi_command_line_array_ptr = 1;
523 mi_command_line_array_cnt = argc;
524
d77f58be 525 if (is_tracepoint (b))
a7bdde9e
VP
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
48cb2d85
VP
531 breakpoint_set_commands (b, break_command);
532}
533