MI: Add -a option to the "-data-disassemble" command
[deliverable/binutils-gdb.git] / gdb / mi / mi-cmd-break.c
CommitLineData
fb40c209 1/* MI Command Set - breakpoint and watchpoint commands.
e2882c85 2 Copyright (C) 2000-2018 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
PA
56 {
57 TRY
58 {
59 print_breakpoint (b);
60 }
61 CATCH (ex, RETURN_MASK_ALL)
62 {
63 exception_print (gdb_stderr, ex);
64 }
65 END_CATCH
66 }
fb40c209
AC
67}
68
fb40c209
AC
69enum bp_type
70 {
71 REG_BP,
72 HW_BP,
73 REGEXP_BP
74 };
75
91985142 76/* Arrange for all new breakpoints and catchpoints to be reported to
00f675ff
TT
77 CURRENT_UIOUT until the destructor of the returned scoped_restore
78 is run.
91985142
MG
79
80 Note that MI output will be probably invalid if more than one
81 breakpoint is created inside one MI command. */
82
00f675ff 83scoped_restore_tmpl<int>
91985142
MG
84setup_breakpoint_reporting (void)
85{
91985142
MG
86 if (! mi_breakpoint_observers_installed)
87 {
76727919 88 gdb::observers::breakpoint_created.attach (breakpoint_notify);
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;
0fb4aa4b 180 enum bptype type_wanted;
ffc2605c 181 event_location_up location;
19ca11c5 182 struct breakpoint_ops *ops;
eb8c4e2e 183 int is_explicit = 0;
67994074 184 struct explicit_location explicit_loc;
784c453a 185 std::string extra_string;
41447f92 186
fb40c209
AC
187 enum opt
188 {
8cdf0e15 189 HARDWARE_OPT, TEMP_OPT, CONDITION_OPT,
6534d786
VP
190 IGNORE_COUNT_OPT, THREAD_OPT, PENDING_OPT, DISABLE_OPT,
191 TRACEPOINT_OPT,
eb8c4e2e
KS
192 EXPLICIT_SOURCE_OPT, EXPLICIT_FUNC_OPT,
193 EXPLICIT_LABEL_OPT, EXPLICIT_LINE_OPT
fb40c209 194 };
91174723 195 static const struct mi_opt opts[] =
fb40c209
AC
196 {
197 {"h", HARDWARE_OPT, 0},
198 {"t", TEMP_OPT, 0},
199 {"c", CONDITION_OPT, 1},
200 {"i", IGNORE_COUNT_OPT, 1},
201 {"p", THREAD_OPT, 1},
afe8ab22 202 {"f", PENDING_OPT, 0},
41447f92 203 {"d", DISABLE_OPT, 0},
6534d786 204 {"a", TRACEPOINT_OPT, 0},
eb8c4e2e
KS
205 {"-source" , EXPLICIT_SOURCE_OPT, 1},
206 {"-function", EXPLICIT_FUNC_OPT, 1},
207 {"-label", EXPLICIT_LABEL_OPT, 1},
208 {"-line", EXPLICIT_LINE_OPT, 1},
d5d6fca5 209 { 0, 0, 0 }
fb40c209
AC
210 };
211
212 /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
213 to denote the end of the option list. */
f8c000a2
AS
214 int oind = 0;
215 char *oarg;
102040f0 216
67994074 217 initialize_explicit_location (&explicit_loc);
eb8c4e2e 218
fb40c209
AC
219 while (1)
220 {
1b05df00 221 int opt = mi_getopt ("-break-insert", argc, argv,
f8c000a2 222 opts, &oind, &oarg);
fb40c209
AC
223 if (opt < 0)
224 break;
225 switch ((enum opt) opt)
226 {
227 case TEMP_OPT:
228 temp_p = 1;
229 break;
230 case HARDWARE_OPT:
8cdf0e15 231 hardware = 1;
fb40c209 232 break;
fb40c209 233 case CONDITION_OPT:
f8c000a2 234 condition = oarg;
fb40c209
AC
235 break;
236 case IGNORE_COUNT_OPT:
f8c000a2 237 ignore_count = atol (oarg);
fb40c209
AC
238 break;
239 case THREAD_OPT:
f8c000a2 240 thread = atol (oarg);
fb40c209 241 break;
afe8ab22
VP
242 case PENDING_OPT:
243 pending = 1;
244 break;
41447f92
VP
245 case DISABLE_OPT:
246 enabled = 0;
6534d786
VP
247 break;
248 case TRACEPOINT_OPT:
249 tracepoint = 1;
250 break;
eb8c4e2e
KS
251 case EXPLICIT_SOURCE_OPT:
252 is_explicit = 1;
67994074 253 explicit_loc.source_filename = oarg;
eb8c4e2e
KS
254 break;
255 case EXPLICIT_FUNC_OPT:
256 is_explicit = 1;
67994074 257 explicit_loc.function_name = oarg;
eb8c4e2e
KS
258 break;
259 case EXPLICIT_LABEL_OPT:
260 is_explicit = 1;
67994074 261 explicit_loc.label_name = oarg;
eb8c4e2e
KS
262 break;
263 case EXPLICIT_LINE_OPT:
264 is_explicit = 1;
67994074 265 explicit_loc.line_offset = linespec_parse_line_offset (oarg);
eb8c4e2e 266 break;
fb40c209
AC
267 }
268 }
269
eb8c4e2e 270 if (oind >= argc && !is_explicit)
c5867ab6
HZ
271 error (_("-%s-insert: Missing <location>"),
272 dprintf ? "dprintf" : "break");
c5867ab6
HZ
273 if (dprintf)
274 {
eb8c4e2e 275 int format_num = is_explicit ? oind : oind + 1;
c5867ab6
HZ
276
277 if (hardware || tracepoint)
278 error (_("-dprintf-insert: does not support -h or -a"));
279 if (format_num >= argc)
280 error (_("-dprintf-insert: Missing <format>"));
281
282 extra_string = mi_argv_to_format (argv + format_num, argc - format_num);
eb8c4e2e 283 address = argv[oind];
c5867ab6
HZ
284 }
285 else
286 {
eb8c4e2e
KS
287 if (is_explicit)
288 {
289 if (oind < argc)
290 error (_("-break-insert: Garbage following explicit location"));
291 }
292 else
293 {
294 if (oind < argc - 1)
295 error (_("-break-insert: Garbage following <location>"));
296 address = argv[oind];
297 }
c5867ab6 298 }
fb40c209 299
2b03b41d 300 /* Now we have what we need, let's insert the breakpoint! */
00f675ff 301 scoped_restore restore_breakpoint_reporting = setup_breakpoint_reporting ();
c5867ab6
HZ
302
303 if (tracepoint)
304 {
305 /* Note that to request a fast tracepoint, the client uses the
306 "hardware" flag, although there's nothing of hardware related to
307 fast tracepoints -- one can implement slow tracepoints with
308 hardware breakpoints, but fast tracepoints are always software.
309 "fast" is a misnomer, actually, "jump" would be more appropriate.
310 A simulator or an emulator could conceivably implement fast
311 regular non-jump based tracepoints. */
312 type_wanted = hardware ? bp_fast_tracepoint : bp_tracepoint;
313 ops = &tracepoint_breakpoint_ops;
314 }
315 else if (dprintf)
316 {
317 type_wanted = bp_dprintf;
318 ops = &dprintf_breakpoint_ops;
319 }
320 else
321 {
322 type_wanted = hardware ? bp_hardware_breakpoint : bp_breakpoint;
323 ops = &bkpt_breakpoint_ops;
324 }
0fb4aa4b 325
eb8c4e2e
KS
326 if (is_explicit)
327 {
328 /* Error check -- we must have one of the other
329 parameters specified. */
67994074
KS
330 if (explicit_loc.source_filename != NULL
331 && explicit_loc.function_name == NULL
332 && explicit_loc.label_name == NULL
333 && explicit_loc.line_offset.sign == LINE_OFFSET_UNKNOWN)
eb8c4e2e
KS
334 error (_("-%s-insert: --source option requires --function, --label,"
335 " or --line"), dprintf ? "dprintf" : "break");
336
67994074 337 location = new_explicit_location (&explicit_loc);
eb8c4e2e
KS
338 }
339 else
340 {
a20714ff
PA
341 location = string_to_event_location_basic (&address, current_language,
342 symbol_name_match_type::WILD);
eb8c4e2e 343 if (*address)
ffc2605c 344 error (_("Garbage '%s' at end of location"), address);
eb8c4e2e 345 }
f00aae0f 346
ffc2605c 347 create_breakpoint (get_current_arch (), location.get (), condition, thread,
784c453a 348 extra_string.c_str (),
8cdf0e15 349 0 /* condition and thread are valid. */,
0fb4aa4b 350 temp_p, type_wanted,
8cdf0e15
VP
351 ignore_count,
352 pending ? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE,
19ca11c5 353 ops, 0, enabled, 0, 0);
c5867ab6
HZ
354}
355
356/* Implements the -break-insert command.
357 See the MI manual for the list of possible options. */
8cdf0e15 358
c5867ab6 359void
9f33b8b7 360mi_cmd_break_insert (const char *command, char **argv, int argc)
c5867ab6
HZ
361{
362 mi_cmd_break_insert_1 (0, command, argv, argc);
363}
364
365/* Implements the -dprintf-insert command.
366 See the MI manual for the list of possible options. */
367
368void
9f33b8b7 369mi_cmd_dprintf_insert (const char *command, char **argv, int argc)
c5867ab6
HZ
370{
371 mi_cmd_break_insert_1 (1, command, argv, argc);
fb40c209
AC
372}
373
374enum wp_type
375{
376 REG_WP,
377 READ_WP,
378 ACCESS_WP
379};
380
9b4c786c 381void
9f33b8b7 382mi_cmd_break_passcount (const char *command, char **argv, int argc)
9b4c786c
VP
383{
384 int n;
385 int p;
d9b3f62e 386 struct tracepoint *t;
9b4c786c
VP
387
388 if (argc != 2)
389 error (_("Usage: tracepoint-number passcount"));
390
391 n = atoi (argv[0]);
392 p = atoi (argv[1]);
393 t = get_tracepoint (n);
394
395 if (t)
396 {
397 t->pass_count = p;
76727919 398 gdb::observers::breakpoint_modified.notify (t);
9b4c786c
VP
399 }
400 else
401 {
401a70b8 402 error (_("Could not find tracepoint %d"), n);
9b4c786c
VP
403 }
404}
405
fb40c209
AC
406/* Insert a watchpoint. The type of watchpoint is specified by the
407 first argument:
408 -break-watch <expr> --> insert a regular wp.
409 -break-watch -r <expr> --> insert a read watchpoint.
2b03b41d 410 -break-watch -a <expr> --> insert an access wp. */
fb40c209 411
ce8f13f8 412void
9f33b8b7 413mi_cmd_break_watch (const char *command, char **argv, int argc)
fb40c209
AC
414{
415 char *expr = NULL;
416 enum wp_type type = REG_WP;
417 enum opt
418 {
419 READ_OPT, ACCESS_OPT
420 };
91174723 421 static const struct mi_opt opts[] =
fb40c209
AC
422 {
423 {"r", READ_OPT, 0},
424 {"a", ACCESS_OPT, 0},
d5d6fca5 425 { 0, 0, 0 }
fb40c209
AC
426 };
427
428 /* Parse arguments. */
f8c000a2
AS
429 int oind = 0;
430 char *oarg;
102040f0 431
fb40c209
AC
432 while (1)
433 {
1b05df00 434 int opt = mi_getopt ("-break-watch", argc, argv,
f8c000a2 435 opts, &oind, &oarg);
102040f0 436
fb40c209
AC
437 if (opt < 0)
438 break;
439 switch ((enum opt) opt)
440 {
441 case READ_OPT:
442 type = READ_WP;
443 break;
444 case ACCESS_OPT:
445 type = ACCESS_WP;
446 break;
447 }
448 }
f8c000a2 449 if (oind >= argc)
1b05df00 450 error (_("-break-watch: Missing <expression>"));
f8c000a2 451 if (oind < argc - 1)
1b05df00 452 error (_("-break-watch: Garbage following <expression>"));
f8c000a2 453 expr = argv[oind];
fb40c209 454
2b03b41d 455 /* Now we have what we need, let's insert the watchpoint! */
fb40c209
AC
456 switch (type)
457 {
458 case REG_WP:
84f4c1fe 459 watch_command_wrapper (expr, FROM_TTY, 0);
fb40c209
AC
460 break;
461 case READ_WP:
84f4c1fe 462 rwatch_command_wrapper (expr, FROM_TTY, 0);
fb40c209
AC
463 break;
464 case ACCESS_WP:
84f4c1fe 465 awatch_command_wrapper (expr, FROM_TTY, 0);
fb40c209
AC
466 break;
467 default:
1b05df00 468 error (_("-break-watch: Unknown watchpoint type."));
fb40c209 469 }
fb40c209 470}
48cb2d85 471
48cb2d85 472void
9f33b8b7 473mi_cmd_break_commands (const char *command, char **argv, int argc)
48cb2d85 474{
12973681 475 counted_command_line break_command;
48cb2d85
VP
476 char *endptr;
477 int bnum;
478 struct breakpoint *b;
479
480 if (argc < 1)
9b20d036 481 error (_("USAGE: %s <BKPT> [<COMMAND> [<COMMAND>...]]"), command);
48cb2d85
VP
482
483 bnum = strtol (argv[0], &endptr, 0);
484 if (endptr == argv[0])
9b20d036 485 error (_("breakpoint number argument \"%s\" is not a number."),
48cb2d85
VP
486 argv[0]);
487 else if (*endptr != '\0')
9b20d036 488 error (_("junk at the end of breakpoint number argument \"%s\"."),
48cb2d85
VP
489 argv[0]);
490
491 b = get_breakpoint (bnum);
492 if (b == NULL)
9b20d036 493 error (_("breakpoint %d not found."), bnum);
48cb2d85 494
60b3cef2
TT
495 int count = 1;
496 auto reader
497 = [&] ()
498 {
499 const char *result = nullptr;
500 if (count < argc)
501 result = argv[count++];
502 return result;
503 };
48cb2d85 504
d77f58be 505 if (is_tracepoint (b))
60b3cef2
TT
506 break_command = read_command_lines_1 (reader, 1,
507 [=] (const char *line)
508 {
509 validate_actionline (line, b);
510 });
a7bdde9e 511 else
60b3cef2 512 break_command = read_command_lines_1 (reader, 1, 0);
a7bdde9e 513
93921405 514 breakpoint_set_commands (b, std::move (break_command));
48cb2d85
VP
515}
516
This page took 1.702594 seconds and 4 git commands to generate.