Automatic Copyright Year update after running gdb/copyright.py
[deliverable/binutils-gdb.git] / gdb / mi / mi-cmd-break.c
CommitLineData
fb40c209 1/* MI Command Set - breakpoint and watchpoint commands.
88b9d363 2 Copyright (C) 2000-2022 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"
76727919 27#include "observable.h"
8d3788bd 28#include "mi-main.h"
91985142 29#include "mi-cmd-break.h"
f00aae0f
KS
30#include "language.h"
31#include "location.h"
32#include "linespec.h"
c5867ab6
HZ
33#include "gdb_obstack.h"
34#include <ctype.h>
60b3cef2 35#include "tracepoint.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)
65630365 56 {
a70b8144 57 try
65630365
PA
58 {
59 print_breakpoint (b);
60 }
230d2906 61 catch (const gdb_exception &ex)
65630365
PA
62 {
63 exception_print (gdb_stderr, ex);
64 }
65630365 65 }
fb40c209
AC
66}
67
fb40c209
AC
68enum bp_type
69 {
70 REG_BP,
71 HW_BP,
72 REGEXP_BP
73 };
74
91985142 75/* Arrange for all new breakpoints and catchpoints to be reported to
00f675ff
TT
76 CURRENT_UIOUT until the destructor of the returned scoped_restore
77 is run.
91985142
MG
78
79 Note that MI output will be probably invalid if more than one
80 breakpoint is created inside one MI command. */
81
00f675ff 82scoped_restore_tmpl<int>
91985142
MG
83setup_breakpoint_reporting (void)
84{
91985142
MG
85 if (! mi_breakpoint_observers_installed)
86 {
c90e7d63
SM
87 gdb::observers::breakpoint_created.attach (breakpoint_notify,
88 "mi-cmd-break");
91985142
MG
89 mi_breakpoint_observers_installed = 1;
90 }
91
00f675ff 92 return make_scoped_restore (&mi_can_breakpoint_notify, 1);
91985142
MG
93}
94
95
c5867ab6
HZ
96/* Convert arguments in ARGV to the string in "format",argv,argv...
97 and return it. */
fb40c209 98
784c453a 99static std::string
c5867ab6
HZ
100mi_argv_to_format (char **argv, int argc)
101{
102 int i;
784c453a 103 std::string result;
c5867ab6
HZ
104
105 /* Convert ARGV[OIND + 1] to format string and save to FORMAT. */
784c453a 106 result += '\"';
c5867ab6
HZ
107 for (i = 0; i < strlen (argv[0]); i++)
108 {
109 switch (argv[0][i])
110 {
111 case '\\':
784c453a 112 result += "\\\\";
c5867ab6
HZ
113 break;
114 case '\a':
784c453a 115 result += "\\a";
c5867ab6
HZ
116 break;
117 case '\b':
784c453a 118 result += "\\b";
c5867ab6
HZ
119 break;
120 case '\f':
784c453a 121 result += "\\f";
c5867ab6
HZ
122 break;
123 case '\n':
784c453a 124 result += "\\n";
c5867ab6
HZ
125 break;
126 case '\r':
784c453a 127 result += "\\r";
c5867ab6
HZ
128 break;
129 case '\t':
784c453a 130 result += "\\t";
c5867ab6
HZ
131 break;
132 case '\v':
784c453a 133 result += "\\v";
c5867ab6 134 break;
fa876972 135 case '"':
784c453a 136 result += "\\\"";
fa876972 137 break;
c5867ab6
HZ
138 default:
139 if (isprint (argv[0][i]))
784c453a 140 result += argv[0][i];
c5867ab6
HZ
141 else
142 {
143 char tmp[5];
144
ce70887a
JB
145 xsnprintf (tmp, sizeof (tmp), "\\%o",
146 (unsigned char) argv[0][i]);
784c453a 147 result += tmp;
c5867ab6
HZ
148 }
149 break;
150 }
151 }
784c453a 152 result += '\"';
c5867ab6
HZ
153
154 /* Apply other argv to FORMAT. */
155 for (i = 1; i < argc; i++)
156 {
784c453a
TT
157 result += ',';
158 result += argv[i];
c5867ab6 159 }
c5867ab6 160
784c453a 161 return result;
c5867ab6
HZ
162}
163
164/* Insert breakpoint.
165 If dprintf is true, it will insert dprintf.
166 If not, it will insert other type breakpoint. */
167
168static void
9f33b8b7 169mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc)
fb40c209 170{
f2fc3015 171 const char *address = NULL;
8cdf0e15 172 int hardware = 0;
fb40c209
AC
173 int temp_p = 0;
174 int thread = -1;
175 int ignore_count = 0;
176 char *condition = NULL;
afe8ab22 177 int pending = 0;
41447f92 178 int enabled = 1;
6534d786 179 int tracepoint = 0;
6791b117 180 symbol_name_match_type match_type = symbol_name_match_type::WILD;
0fb4aa4b 181 enum bptype type_wanted;
ffc2605c 182 event_location_up location;
19ca11c5 183 struct breakpoint_ops *ops;
eb8c4e2e 184 int is_explicit = 0;
67994074 185 struct explicit_location explicit_loc;
784c453a 186 std::string extra_string;
10e578d7 187 bool force_condition = false;
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,
10e578d7 194 FORCE_CONDITION_OPT,
6791b117 195 QUALIFIED_OPT,
eb8c4e2e
KS
196 EXPLICIT_SOURCE_OPT, EXPLICIT_FUNC_OPT,
197 EXPLICIT_LABEL_OPT, EXPLICIT_LINE_OPT
fb40c209 198 };
91174723 199 static const struct mi_opt opts[] =
fb40c209
AC
200 {
201 {"h", HARDWARE_OPT, 0},
202 {"t", TEMP_OPT, 0},
203 {"c", CONDITION_OPT, 1},
204 {"i", IGNORE_COUNT_OPT, 1},
205 {"p", THREAD_OPT, 1},
afe8ab22 206 {"f", PENDING_OPT, 0},
41447f92 207 {"d", DISABLE_OPT, 0},
6534d786 208 {"a", TRACEPOINT_OPT, 0},
10e578d7 209 {"-force-condition", FORCE_CONDITION_OPT, 0},
6791b117 210 {"-qualified", QUALIFIED_OPT, 0},
eb8c4e2e
KS
211 {"-source" , EXPLICIT_SOURCE_OPT, 1},
212 {"-function", EXPLICIT_FUNC_OPT, 1},
213 {"-label", EXPLICIT_LABEL_OPT, 1},
214 {"-line", EXPLICIT_LINE_OPT, 1},
d5d6fca5 215 { 0, 0, 0 }
fb40c209
AC
216 };
217
218 /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
219 to denote the end of the option list. */
f8c000a2
AS
220 int oind = 0;
221 char *oarg;
102040f0 222
67994074 223 initialize_explicit_location (&explicit_loc);
eb8c4e2e 224
fb40c209
AC
225 while (1)
226 {
1b05df00 227 int opt = mi_getopt ("-break-insert", argc, argv,
f8c000a2 228 opts, &oind, &oarg);
fb40c209
AC
229 if (opt < 0)
230 break;
231 switch ((enum opt) opt)
232 {
233 case TEMP_OPT:
234 temp_p = 1;
235 break;
236 case HARDWARE_OPT:
8cdf0e15 237 hardware = 1;
fb40c209 238 break;
fb40c209 239 case CONDITION_OPT:
f8c000a2 240 condition = oarg;
fb40c209
AC
241 break;
242 case IGNORE_COUNT_OPT:
f8c000a2 243 ignore_count = atol (oarg);
fb40c209
AC
244 break;
245 case THREAD_OPT:
f8c000a2 246 thread = atol (oarg);
fb40c209 247 break;
afe8ab22
VP
248 case PENDING_OPT:
249 pending = 1;
250 break;
41447f92
VP
251 case DISABLE_OPT:
252 enabled = 0;
6534d786
VP
253 break;
254 case TRACEPOINT_OPT:
255 tracepoint = 1;
256 break;
6791b117
PA
257 case QUALIFIED_OPT:
258 match_type = symbol_name_match_type::FULL;
259 break;
eb8c4e2e
KS
260 case EXPLICIT_SOURCE_OPT:
261 is_explicit = 1;
67994074 262 explicit_loc.source_filename = oarg;
eb8c4e2e
KS
263 break;
264 case EXPLICIT_FUNC_OPT:
265 is_explicit = 1;
67994074 266 explicit_loc.function_name = oarg;
eb8c4e2e
KS
267 break;
268 case EXPLICIT_LABEL_OPT:
269 is_explicit = 1;
67994074 270 explicit_loc.label_name = oarg;
eb8c4e2e
KS
271 break;
272 case EXPLICIT_LINE_OPT:
273 is_explicit = 1;
67994074 274 explicit_loc.line_offset = linespec_parse_line_offset (oarg);
eb8c4e2e 275 break;
10e578d7
TBA
276 case FORCE_CONDITION_OPT:
277 force_condition = true;
278 break;
fb40c209
AC
279 }
280 }
281
eb8c4e2e 282 if (oind >= argc && !is_explicit)
c5867ab6
HZ
283 error (_("-%s-insert: Missing <location>"),
284 dprintf ? "dprintf" : "break");
c5867ab6
HZ
285 if (dprintf)
286 {
eb8c4e2e 287 int format_num = is_explicit ? oind : oind + 1;
c5867ab6
HZ
288
289 if (hardware || tracepoint)
290 error (_("-dprintf-insert: does not support -h or -a"));
291 if (format_num >= argc)
292 error (_("-dprintf-insert: Missing <format>"));
293
294 extra_string = mi_argv_to_format (argv + format_num, argc - format_num);
eb8c4e2e 295 address = argv[oind];
c5867ab6
HZ
296 }
297 else
298 {
eb8c4e2e
KS
299 if (is_explicit)
300 {
301 if (oind < argc)
302 error (_("-break-insert: Garbage following explicit location"));
303 }
304 else
305 {
306 if (oind < argc - 1)
307 error (_("-break-insert: Garbage following <location>"));
308 address = argv[oind];
309 }
c5867ab6 310 }
fb40c209 311
2b03b41d 312 /* Now we have what we need, let's insert the breakpoint! */
00f675ff 313 scoped_restore restore_breakpoint_reporting = setup_breakpoint_reporting ();
c5867ab6
HZ
314
315 if (tracepoint)
316 {
317 /* Note that to request a fast tracepoint, the client uses the
318 "hardware" flag, although there's nothing of hardware related to
319 fast tracepoints -- one can implement slow tracepoints with
320 hardware breakpoints, but fast tracepoints are always software.
321 "fast" is a misnomer, actually, "jump" would be more appropriate.
322 A simulator or an emulator could conceivably implement fast
323 regular non-jump based tracepoints. */
324 type_wanted = hardware ? bp_fast_tracepoint : bp_tracepoint;
325 ops = &tracepoint_breakpoint_ops;
326 }
327 else if (dprintf)
328 {
329 type_wanted = bp_dprintf;
330 ops = &dprintf_breakpoint_ops;
331 }
332 else
333 {
334 type_wanted = hardware ? bp_hardware_breakpoint : bp_breakpoint;
335 ops = &bkpt_breakpoint_ops;
336 }
0fb4aa4b 337
eb8c4e2e
KS
338 if (is_explicit)
339 {
340 /* Error check -- we must have one of the other
341 parameters specified. */
67994074
KS
342 if (explicit_loc.source_filename != NULL
343 && explicit_loc.function_name == NULL
344 && explicit_loc.label_name == NULL
345 && explicit_loc.line_offset.sign == LINE_OFFSET_UNKNOWN)
eb8c4e2e
KS
346 error (_("-%s-insert: --source option requires --function, --label,"
347 " or --line"), dprintf ? "dprintf" : "break");
348
6791b117
PA
349 explicit_loc.func_name_match_type = match_type;
350
67994074 351 location = new_explicit_location (&explicit_loc);
eb8c4e2e
KS
352 }
353 else
354 {
a20714ff 355 location = string_to_event_location_basic (&address, current_language,
6791b117 356 match_type);
eb8c4e2e 357 if (*address)
ffc2605c 358 error (_("Garbage '%s' at end of location"), address);
eb8c4e2e 359 }
f00aae0f 360
ffc2605c 361 create_breakpoint (get_current_arch (), location.get (), condition, thread,
784c453a 362 extra_string.c_str (),
10e578d7 363 force_condition,
8cdf0e15 364 0 /* condition and thread are valid. */,
0fb4aa4b 365 temp_p, type_wanted,
8cdf0e15
VP
366 ignore_count,
367 pending ? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE,
19ca11c5 368 ops, 0, enabled, 0, 0);
c5867ab6
HZ
369}
370
371/* Implements the -break-insert command.
372 See the MI manual for the list of possible options. */
8cdf0e15 373
c5867ab6 374void
9f33b8b7 375mi_cmd_break_insert (const char *command, char **argv, int argc)
c5867ab6
HZ
376{
377 mi_cmd_break_insert_1 (0, command, argv, argc);
378}
379
380/* Implements the -dprintf-insert command.
381 See the MI manual for the list of possible options. */
382
383void
9f33b8b7 384mi_cmd_dprintf_insert (const char *command, char **argv, int argc)
c5867ab6
HZ
385{
386 mi_cmd_break_insert_1 (1, command, argv, argc);
fb40c209
AC
387}
388
79aabb73
TBA
389/* Implements the -break-condition command.
390 See the MI manual for the list of options. */
391
392void
393mi_cmd_break_condition (const char *command, char **argv, int argc)
394{
395 enum option
396 {
397 FORCE_CONDITION_OPT,
398 };
399
400 static const struct mi_opt opts[] =
401 {
402 {"-force", FORCE_CONDITION_OPT, 0},
403 { 0, 0, 0 }
404 };
405
406 /* Parse arguments. */
407 int oind = 0;
408 char *oarg;
409 bool force_condition = false;
410
411 while (true)
412 {
413 int opt = mi_getopt ("-break-condition", argc, argv,
414 opts, &oind, &oarg);
415 if (opt < 0)
416 break;
417
418 switch (opt)
419 {
420 case FORCE_CONDITION_OPT:
421 force_condition = true;
422 break;
423 }
424 }
425
86271cfa
TBA
426 /* There must be at least one more arg: a bpnum. */
427 if (oind >= argc)
428 error (_("-break-condition: Missing the <number> argument"));
79aabb73
TBA
429
430 int bpnum = atoi (argv[oind]);
431
432 /* The rest form the condition expr. */
86271cfa
TBA
433 std::string expr = "";
434 for (int i = oind + 1; i < argc; ++i)
79aabb73 435 {
79aabb73 436 expr += argv[i];
86271cfa
TBA
437 if (i + 1 < argc)
438 expr += " ";
79aabb73
TBA
439 }
440
441 set_breakpoint_condition (bpnum, expr.c_str (), 0 /* from_tty */,
442 force_condition);
443}
444
fb40c209
AC
445enum wp_type
446{
447 REG_WP,
448 READ_WP,
449 ACCESS_WP
450};
451
9b4c786c 452void
9f33b8b7 453mi_cmd_break_passcount (const char *command, char **argv, int argc)
9b4c786c
VP
454{
455 int n;
456 int p;
d9b3f62e 457 struct tracepoint *t;
9b4c786c
VP
458
459 if (argc != 2)
460 error (_("Usage: tracepoint-number passcount"));
461
462 n = atoi (argv[0]);
463 p = atoi (argv[1]);
464 t = get_tracepoint (n);
465
466 if (t)
467 {
468 t->pass_count = p;
76727919 469 gdb::observers::breakpoint_modified.notify (t);
9b4c786c
VP
470 }
471 else
472 {
401a70b8 473 error (_("Could not find tracepoint %d"), n);
9b4c786c
VP
474 }
475}
476
fb40c209
AC
477/* Insert a watchpoint. The type of watchpoint is specified by the
478 first argument:
479 -break-watch <expr> --> insert a regular wp.
480 -break-watch -r <expr> --> insert a read watchpoint.
2b03b41d 481 -break-watch -a <expr> --> insert an access wp. */
fb40c209 482
ce8f13f8 483void
9f33b8b7 484mi_cmd_break_watch (const char *command, char **argv, int argc)
fb40c209
AC
485{
486 char *expr = NULL;
487 enum wp_type type = REG_WP;
488 enum opt
489 {
490 READ_OPT, ACCESS_OPT
491 };
91174723 492 static const struct mi_opt opts[] =
fb40c209
AC
493 {
494 {"r", READ_OPT, 0},
495 {"a", ACCESS_OPT, 0},
d5d6fca5 496 { 0, 0, 0 }
fb40c209
AC
497 };
498
499 /* Parse arguments. */
f8c000a2
AS
500 int oind = 0;
501 char *oarg;
102040f0 502
fb40c209
AC
503 while (1)
504 {
1b05df00 505 int opt = mi_getopt ("-break-watch", argc, argv,
f8c000a2 506 opts, &oind, &oarg);
102040f0 507
fb40c209
AC
508 if (opt < 0)
509 break;
510 switch ((enum opt) opt)
511 {
512 case READ_OPT:
513 type = READ_WP;
514 break;
515 case ACCESS_OPT:
516 type = ACCESS_WP;
517 break;
518 }
519 }
f8c000a2 520 if (oind >= argc)
1b05df00 521 error (_("-break-watch: Missing <expression>"));
f8c000a2 522 if (oind < argc - 1)
1b05df00 523 error (_("-break-watch: Garbage following <expression>"));
f8c000a2 524 expr = argv[oind];
fb40c209 525
2b03b41d 526 /* Now we have what we need, let's insert the watchpoint! */
fb40c209
AC
527 switch (type)
528 {
529 case REG_WP:
2e362716 530 watch_command_wrapper (expr, FROM_TTY, false);
fb40c209
AC
531 break;
532 case READ_WP:
2e362716 533 rwatch_command_wrapper (expr, FROM_TTY, false);
fb40c209
AC
534 break;
535 case ACCESS_WP:
2e362716 536 awatch_command_wrapper (expr, FROM_TTY, false);
fb40c209
AC
537 break;
538 default:
1b05df00 539 error (_("-break-watch: Unknown watchpoint type."));
fb40c209 540 }
fb40c209 541}
48cb2d85 542
48cb2d85 543void
9f33b8b7 544mi_cmd_break_commands (const char *command, char **argv, int argc)
48cb2d85 545{
12973681 546 counted_command_line break_command;
48cb2d85
VP
547 char *endptr;
548 int bnum;
549 struct breakpoint *b;
550
551 if (argc < 1)
9b20d036 552 error (_("USAGE: %s <BKPT> [<COMMAND> [<COMMAND>...]]"), command);
48cb2d85
VP
553
554 bnum = strtol (argv[0], &endptr, 0);
555 if (endptr == argv[0])
9b20d036 556 error (_("breakpoint number argument \"%s\" is not a number."),
48cb2d85
VP
557 argv[0]);
558 else if (*endptr != '\0')
9b20d036 559 error (_("junk at the end of breakpoint number argument \"%s\"."),
48cb2d85
VP
560 argv[0]);
561
562 b = get_breakpoint (bnum);
563 if (b == NULL)
9b20d036 564 error (_("breakpoint %d not found."), bnum);
48cb2d85 565
60b3cef2
TT
566 int count = 1;
567 auto reader
568 = [&] ()
569 {
570 const char *result = nullptr;
571 if (count < argc)
572 result = argv[count++];
573 return result;
574 };
48cb2d85 575
d77f58be 576 if (is_tracepoint (b))
60b3cef2
TT
577 break_command = read_command_lines_1 (reader, 1,
578 [=] (const char *line)
579 {
580 validate_actionline (line, b);
581 });
a7bdde9e 582 else
60b3cef2 583 break_command = read_command_lines_1 (reader, 1, 0);
a7bdde9e 584
93921405 585 breakpoint_set_commands (b, std::move (break_command));
48cb2d85
VP
586}
587
This page took 2.342881 seconds and 4 git commands to generate.