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