1 /* MI Command Set - breakpoint and watchpoint commands.
2 Copyright (C) 2000-2017 Free Software Foundation, Inc.
3 Contributed by Cygnus Solutions (a Red Hat company).
5 This file is part of GDB.
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
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
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.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 #include "arch-utils.h"
25 #include "breakpoint.h"
26 #include "mi-getopt.h"
30 #include "mi-cmd-break.h"
34 #include "gdb_obstack.h"
42 /* True if MI breakpoint observers have been registered. */
44 static int mi_breakpoint_observers_installed
;
46 /* Control whether breakpoint_notify may act. */
48 static int mi_can_breakpoint_notify
;
50 /* Output a single breakpoint, when allowed. */
53 breakpoint_notify (struct breakpoint
*b
)
55 if (mi_can_breakpoint_notify
)
56 gdb_breakpoint_query (current_uiout
, b
->number
, NULL
);
66 /* Arrange for all new breakpoints and catchpoints to be reported to
67 CURRENT_UIOUT until the cleanup returned by this function is run.
69 Note that MI output will be probably invalid if more than one
70 breakpoint is created inside one MI command. */
73 setup_breakpoint_reporting (void)
75 struct cleanup
*rev_flag
;
77 if (! mi_breakpoint_observers_installed
)
79 observer_attach_breakpoint_created (breakpoint_notify
);
80 mi_breakpoint_observers_installed
= 1;
83 rev_flag
= make_cleanup_restore_integer (&mi_can_breakpoint_notify
);
84 mi_can_breakpoint_notify
= 1;
90 /* Convert arguments in ARGV to the string in "format",argv,argv...
94 mi_argv_to_format (char **argv
, int argc
)
97 struct obstack obstack
;
100 obstack_init (&obstack
);
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
++)
109 obstack_grow (&obstack
, "\\\\", 2);
112 obstack_grow (&obstack
, "\\a", 2);
115 obstack_grow (&obstack
, "\\b", 2);
118 obstack_grow (&obstack
, "\\f", 2);
121 obstack_grow (&obstack
, "\\n", 2);
124 obstack_grow (&obstack
, "\\r", 2);
127 obstack_grow (&obstack
, "\\t", 2);
130 obstack_grow (&obstack
, "\\v", 2);
133 obstack_grow (&obstack
, "\\\"", 2);
136 if (isprint (argv
[0][i
]))
137 obstack_grow (&obstack
, argv
[0] + i
, 1);
142 xsnprintf (tmp
, sizeof (tmp
), "\\%o",
143 (unsigned char) argv
[0][i
]);
144 obstack_grow (&obstack
, tmp
, strlen (tmp
));
149 obstack_1grow (&obstack
, '\"');
151 /* Apply other argv to FORMAT. */
152 for (i
= 1; i
< argc
; i
++)
154 obstack_1grow (&obstack
, ',');
155 obstack_grow (&obstack
, argv
[i
], strlen (argv
[i
]));
157 obstack_1grow (&obstack
, '\0');
159 ret
= xstrdup ((const char *) obstack_finish (&obstack
));
160 obstack_free (&obstack
, NULL
);
165 /* Insert breakpoint.
166 If dprintf is true, it will insert dprintf.
167 If not, it will insert other type breakpoint. */
170 mi_cmd_break_insert_1 (int dprintf
, char *command
, char **argv
, int argc
)
172 char *address
= NULL
;
176 int ignore_count
= 0;
177 char *condition
= NULL
;
181 struct cleanup
*back_to
= make_cleanup (null_cleanup
, NULL
);
182 enum bptype type_wanted
;
183 struct event_location
*location
;
184 struct breakpoint_ops
*ops
;
186 struct explicit_location explicit_loc
;
187 char *extra_string
= NULL
;
191 HARDWARE_OPT
, TEMP_OPT
, CONDITION_OPT
,
192 IGNORE_COUNT_OPT
, THREAD_OPT
, PENDING_OPT
, DISABLE_OPT
,
194 EXPLICIT_SOURCE_OPT
, EXPLICIT_FUNC_OPT
,
195 EXPLICIT_LABEL_OPT
, EXPLICIT_LINE_OPT
197 static const struct mi_opt opts
[] =
199 {"h", HARDWARE_OPT
, 0},
201 {"c", CONDITION_OPT
, 1},
202 {"i", IGNORE_COUNT_OPT
, 1},
203 {"p", THREAD_OPT
, 1},
204 {"f", PENDING_OPT
, 0},
205 {"d", DISABLE_OPT
, 0},
206 {"a", TRACEPOINT_OPT
, 0},
207 {"-source" , EXPLICIT_SOURCE_OPT
, 1},
208 {"-function", EXPLICIT_FUNC_OPT
, 1},
209 {"-label", EXPLICIT_LABEL_OPT
, 1},
210 {"-line", EXPLICIT_LINE_OPT
, 1},
214 /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
215 to denote the end of the option list. */
219 initialize_explicit_location (&explicit_loc
);
223 int opt
= mi_getopt ("-break-insert", argc
, argv
,
227 switch ((enum opt
) opt
)
238 case IGNORE_COUNT_OPT
:
239 ignore_count
= atol (oarg
);
242 thread
= atol (oarg
);
253 case EXPLICIT_SOURCE_OPT
:
255 explicit_loc
.source_filename
= oarg
;
257 case EXPLICIT_FUNC_OPT
:
259 explicit_loc
.function_name
= oarg
;
261 case EXPLICIT_LABEL_OPT
:
263 explicit_loc
.label_name
= oarg
;
265 case EXPLICIT_LINE_OPT
:
267 explicit_loc
.line_offset
= linespec_parse_line_offset (oarg
);
272 if (oind
>= argc
&& !is_explicit
)
273 error (_("-%s-insert: Missing <location>"),
274 dprintf
? "dprintf" : "break");
277 int format_num
= is_explicit
? oind
: oind
+ 1;
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>"));
284 extra_string
= mi_argv_to_format (argv
+ format_num
, argc
- format_num
);
285 make_cleanup (xfree
, extra_string
);
286 address
= argv
[oind
];
293 error (_("-break-insert: Garbage following explicit location"));
298 error (_("-break-insert: Garbage following <location>"));
299 address
= argv
[oind
];
303 /* Now we have what we need, let's insert the breakpoint! */
304 setup_breakpoint_reporting ();
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
;
320 type_wanted
= bp_dprintf
;
321 ops
= &dprintf_breakpoint_ops
;
325 type_wanted
= hardware
? bp_hardware_breakpoint
: bp_breakpoint
;
326 ops
= &bkpt_breakpoint_ops
;
331 /* Error check -- we must have one of the other
332 parameters specified. */
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
)
337 error (_("-%s-insert: --source option requires --function, --label,"
338 " or --line"), dprintf
? "dprintf" : "break");
340 location
= new_explicit_location (&explicit_loc
);
344 location
= string_to_event_location_basic (&address
, current_language
);
347 delete_event_location (location
);
348 error (_("Garbage '%s' at end of location"), address
);
352 make_cleanup_delete_event_location (location
);
354 create_breakpoint (get_current_arch (), location
, condition
, thread
,
356 0 /* condition and thread are valid. */,
359 pending
? AUTO_BOOLEAN_TRUE
: AUTO_BOOLEAN_FALSE
,
360 ops
, 0, enabled
, 0, 0);
361 do_cleanups (back_to
);
364 /* Implements the -break-insert command.
365 See the MI manual for the list of possible options. */
368 mi_cmd_break_insert (char *command
, char **argv
, int argc
)
370 mi_cmd_break_insert_1 (0, command
, argv
, argc
);
373 /* Implements the -dprintf-insert command.
374 See the MI manual for the list of possible options. */
377 mi_cmd_dprintf_insert (char *command
, char **argv
, int argc
)
379 mi_cmd_break_insert_1 (1, command
, argv
, argc
);
390 mi_cmd_break_passcount (char *command
, char **argv
, int argc
)
394 struct tracepoint
*t
;
397 error (_("Usage: tracepoint-number passcount"));
401 t
= get_tracepoint (n
);
406 observer_notify_breakpoint_modified (&t
->base
);
410 error (_("Could not find tracepoint %d"), n
);
414 /* Insert a watchpoint. The type of watchpoint is specified by the
416 -break-watch <expr> --> insert a regular wp.
417 -break-watch -r <expr> --> insert a read watchpoint.
418 -break-watch -a <expr> --> insert an access wp. */
421 mi_cmd_break_watch (char *command
, char **argv
, int argc
)
424 enum wp_type type
= REG_WP
;
429 static const struct mi_opt opts
[] =
432 {"a", ACCESS_OPT
, 0},
436 /* Parse arguments. */
442 int opt
= mi_getopt ("-break-watch", argc
, argv
,
447 switch ((enum opt
) opt
)
458 error (_("-break-watch: Missing <expression>"));
460 error (_("-break-watch: Garbage following <expression>"));
463 /* Now we have what we need, let's insert the watchpoint! */
467 watch_command_wrapper (expr
, FROM_TTY
, 0);
470 rwatch_command_wrapper (expr
, FROM_TTY
, 0);
473 awatch_command_wrapper (expr
, FROM_TTY
, 0);
476 error (_("-break-watch: Unknown watchpoint type."));
480 /* The mi_read_next_line consults these variable to return successive
481 command lines. While it would be clearer to use a closure pointer,
482 it is not expected that any future code will use read_command_lines_1,
483 therefore no point of overengineering. */
485 static char **mi_command_line_array
;
486 static int mi_command_line_array_cnt
;
487 static int mi_command_line_array_ptr
;
490 mi_read_next_line (void)
492 if (mi_command_line_array_ptr
== mi_command_line_array_cnt
)
495 return mi_command_line_array
[mi_command_line_array_ptr
++];
499 mi_cmd_break_commands (char *command
, char **argv
, int argc
)
501 struct command_line
*break_command
;
504 struct breakpoint
*b
;
507 error (_("USAGE: %s <BKPT> [<COMMAND> [<COMMAND>...]]"), command
);
509 bnum
= strtol (argv
[0], &endptr
, 0);
510 if (endptr
== argv
[0])
511 error (_("breakpoint number argument \"%s\" is not a number."),
513 else if (*endptr
!= '\0')
514 error (_("junk at the end of breakpoint number argument \"%s\"."),
517 b
= get_breakpoint (bnum
);
519 error (_("breakpoint %d not found."), bnum
);
521 mi_command_line_array
= argv
;
522 mi_command_line_array_ptr
= 1;
523 mi_command_line_array_cnt
= argc
;
525 if (is_tracepoint (b
))
526 break_command
= read_command_lines_1 (mi_read_next_line
, 1,
527 check_tracepoint_command
, b
);
529 break_command
= read_command_lines_1 (mi_read_next_line
, 1, 0, 0);
531 breakpoint_set_commands (b
, break_command
);