Rename gdb exception types
[deliverable/binutils-gdb.git] / gdb / mi / mi-cmd-break.c
CommitLineData
fb40c209 1/* MI Command Set - breakpoint and watchpoint commands.
42a4f53d 2 Copyright (C) 2000-2019 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 {
76727919 87 gdb::observers::breakpoint_created.attach (breakpoint_notify);
91985142
MG
88 mi_breakpoint_observers_installed = 1;
89 }
90
00f675ff 91 return make_scoped_restore (&mi_can_breakpoint_notify, 1);
91985142
MG
92}
93
94
c5867ab6
HZ
95/* Convert arguments in ARGV to the string in "format",argv,argv...
96 and return it. */
fb40c209 97
784c453a 98static std::string
c5867ab6
HZ
99mi_argv_to_format (char **argv, int argc)
100{
101 int i;
784c453a 102 std::string result;
c5867ab6
HZ
103
104 /* Convert ARGV[OIND + 1] to format string and save to FORMAT. */
784c453a 105 result += '\"';
c5867ab6
HZ
106 for (i = 0; i < strlen (argv[0]); i++)
107 {
108 switch (argv[0][i])
109 {
110 case '\\':
784c453a 111 result += "\\\\";
c5867ab6
HZ
112 break;
113 case '\a':
784c453a 114 result += "\\a";
c5867ab6
HZ
115 break;
116 case '\b':
784c453a 117 result += "\\b";
c5867ab6
HZ
118 break;
119 case '\f':
784c453a 120 result += "\\f";
c5867ab6
HZ
121 break;
122 case '\n':
784c453a 123 result += "\\n";
c5867ab6
HZ
124 break;
125 case '\r':
784c453a 126 result += "\\r";
c5867ab6
HZ
127 break;
128 case '\t':
784c453a 129 result += "\\t";
c5867ab6
HZ
130 break;
131 case '\v':
784c453a 132 result += "\\v";
c5867ab6 133 break;
fa876972 134 case '"':
784c453a 135 result += "\\\"";
fa876972 136 break;
c5867ab6
HZ
137 default:
138 if (isprint (argv[0][i]))
784c453a 139 result += argv[0][i];
c5867ab6
HZ
140 else
141 {
142 char tmp[5];
143
ce70887a
JB
144 xsnprintf (tmp, sizeof (tmp), "\\%o",
145 (unsigned char) argv[0][i]);
784c453a 146 result += tmp;
c5867ab6
HZ
147 }
148 break;
149 }
150 }
784c453a 151 result += '\"';
c5867ab6
HZ
152
153 /* Apply other argv to FORMAT. */
154 for (i = 1; i < argc; i++)
155 {
784c453a
TT
156 result += ',';
157 result += argv[i];
c5867ab6 158 }
c5867ab6 159
784c453a 160 return result;
c5867ab6
HZ
161}
162
163/* Insert breakpoint.
164 If dprintf is true, it will insert dprintf.
165 If not, it will insert other type breakpoint. */
166
167static void
9f33b8b7 168mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc)
fb40c209 169{
f2fc3015 170 const char *address = NULL;
8cdf0e15 171 int hardware = 0;
fb40c209
AC
172 int temp_p = 0;
173 int thread = -1;
174 int ignore_count = 0;
175 char *condition = NULL;
afe8ab22 176 int pending = 0;
41447f92 177 int enabled = 1;
6534d786 178 int tracepoint = 0;
0fb4aa4b 179 enum bptype type_wanted;
ffc2605c 180 event_location_up location;
19ca11c5 181 struct breakpoint_ops *ops;
eb8c4e2e 182 int is_explicit = 0;
67994074 183 struct explicit_location explicit_loc;
784c453a 184 std::string extra_string;
41447f92 185
fb40c209
AC
186 enum opt
187 {
8cdf0e15 188 HARDWARE_OPT, TEMP_OPT, CONDITION_OPT,
6534d786
VP
189 IGNORE_COUNT_OPT, THREAD_OPT, PENDING_OPT, DISABLE_OPT,
190 TRACEPOINT_OPT,
eb8c4e2e
KS
191 EXPLICIT_SOURCE_OPT, EXPLICIT_FUNC_OPT,
192 EXPLICIT_LABEL_OPT, EXPLICIT_LINE_OPT
fb40c209 193 };
91174723 194 static const struct mi_opt opts[] =
fb40c209
AC
195 {
196 {"h", HARDWARE_OPT, 0},
197 {"t", TEMP_OPT, 0},
198 {"c", CONDITION_OPT, 1},
199 {"i", IGNORE_COUNT_OPT, 1},
200 {"p", THREAD_OPT, 1},
afe8ab22 201 {"f", PENDING_OPT, 0},
41447f92 202 {"d", DISABLE_OPT, 0},
6534d786 203 {"a", TRACEPOINT_OPT, 0},
eb8c4e2e
KS
204 {"-source" , EXPLICIT_SOURCE_OPT, 1},
205 {"-function", EXPLICIT_FUNC_OPT, 1},
206 {"-label", EXPLICIT_LABEL_OPT, 1},
207 {"-line", EXPLICIT_LINE_OPT, 1},
d5d6fca5 208 { 0, 0, 0 }
fb40c209
AC
209 };
210
211 /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
212 to denote the end of the option list. */
f8c000a2
AS
213 int oind = 0;
214 char *oarg;
102040f0 215
67994074 216 initialize_explicit_location (&explicit_loc);
eb8c4e2e 217
fb40c209
AC
218 while (1)
219 {
1b05df00 220 int opt = mi_getopt ("-break-insert", argc, argv,
f8c000a2 221 opts, &oind, &oarg);
fb40c209
AC
222 if (opt < 0)
223 break;
224 switch ((enum opt) opt)
225 {
226 case TEMP_OPT:
227 temp_p = 1;
228 break;
229 case HARDWARE_OPT:
8cdf0e15 230 hardware = 1;
fb40c209 231 break;
fb40c209 232 case CONDITION_OPT:
f8c000a2 233 condition = oarg;
fb40c209
AC
234 break;
235 case IGNORE_COUNT_OPT:
f8c000a2 236 ignore_count = atol (oarg);
fb40c209
AC
237 break;
238 case THREAD_OPT:
f8c000a2 239 thread = atol (oarg);
fb40c209 240 break;
afe8ab22
VP
241 case PENDING_OPT:
242 pending = 1;
243 break;
41447f92
VP
244 case DISABLE_OPT:
245 enabled = 0;
6534d786
VP
246 break;
247 case TRACEPOINT_OPT:
248 tracepoint = 1;
249 break;
eb8c4e2e
KS
250 case EXPLICIT_SOURCE_OPT:
251 is_explicit = 1;
67994074 252 explicit_loc.source_filename = oarg;
eb8c4e2e
KS
253 break;
254 case EXPLICIT_FUNC_OPT:
255 is_explicit = 1;
67994074 256 explicit_loc.function_name = oarg;
eb8c4e2e
KS
257 break;
258 case EXPLICIT_LABEL_OPT:
259 is_explicit = 1;
67994074 260 explicit_loc.label_name = oarg;
eb8c4e2e
KS
261 break;
262 case EXPLICIT_LINE_OPT:
263 is_explicit = 1;
67994074 264 explicit_loc.line_offset = linespec_parse_line_offset (oarg);
eb8c4e2e 265 break;
fb40c209
AC
266 }
267 }
268
eb8c4e2e 269 if (oind >= argc && !is_explicit)
c5867ab6
HZ
270 error (_("-%s-insert: Missing <location>"),
271 dprintf ? "dprintf" : "break");
c5867ab6
HZ
272 if (dprintf)
273 {
eb8c4e2e 274 int format_num = is_explicit ? oind : oind + 1;
c5867ab6
HZ
275
276 if (hardware || tracepoint)
277 error (_("-dprintf-insert: does not support -h or -a"));
278 if (format_num >= argc)
279 error (_("-dprintf-insert: Missing <format>"));
280
281 extra_string = mi_argv_to_format (argv + format_num, argc - format_num);
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 {
a20714ff
PA
340 location = string_to_event_location_basic (&address, current_language,
341 symbol_name_match_type::WILD);
eb8c4e2e 342 if (*address)
ffc2605c 343 error (_("Garbage '%s' at end of location"), address);
eb8c4e2e 344 }
f00aae0f 345
ffc2605c 346 create_breakpoint (get_current_arch (), location.get (), condition, thread,
784c453a 347 extra_string.c_str (),
8cdf0e15 348 0 /* condition and thread are valid. */,
0fb4aa4b 349 temp_p, type_wanted,
8cdf0e15
VP
350 ignore_count,
351 pending ? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE,
19ca11c5 352 ops, 0, enabled, 0, 0);
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;
76727919 397 gdb::observers::breakpoint_modified.notify (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 470
48cb2d85 471void
9f33b8b7 472mi_cmd_break_commands (const char *command, char **argv, int argc)
48cb2d85 473{
12973681 474 counted_command_line break_command;
48cb2d85
VP
475 char *endptr;
476 int bnum;
477 struct breakpoint *b;
478
479 if (argc < 1)
9b20d036 480 error (_("USAGE: %s <BKPT> [<COMMAND> [<COMMAND>...]]"), command);
48cb2d85
VP
481
482 bnum = strtol (argv[0], &endptr, 0);
483 if (endptr == argv[0])
9b20d036 484 error (_("breakpoint number argument \"%s\" is not a number."),
48cb2d85
VP
485 argv[0]);
486 else if (*endptr != '\0')
9b20d036 487 error (_("junk at the end of breakpoint number argument \"%s\"."),
48cb2d85
VP
488 argv[0]);
489
490 b = get_breakpoint (bnum);
491 if (b == NULL)
9b20d036 492 error (_("breakpoint %d not found."), bnum);
48cb2d85 493
60b3cef2
TT
494 int count = 1;
495 auto reader
496 = [&] ()
497 {
498 const char *result = nullptr;
499 if (count < argc)
500 result = argv[count++];
501 return result;
502 };
48cb2d85 503
d77f58be 504 if (is_tracepoint (b))
60b3cef2
TT
505 break_command = read_command_lines_1 (reader, 1,
506 [=] (const char *line)
507 {
508 validate_actionline (line, b);
509 });
a7bdde9e 510 else
60b3cef2 511 break_command = read_command_lines_1 (reader, 1, 0);
a7bdde9e 512
93921405 513 breakpoint_set_commands (b, std::move (break_command));
48cb2d85
VP
514}
515
This page took 1.914694 seconds and 4 git commands to generate.