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