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