1 /* MI Command Set - breakpoint and watchpoint commands.
2 Copyright (C) 2000-2013 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 "gdb_string.h"
27 #include "mi-getopt.h"
29 #include "exceptions.h"
32 #include "mi-cmd-break.h"
39 /* True if MI breakpoint observers have been registered. */
41 static int mi_breakpoint_observers_installed;
43 /* Control whether breakpoint_notify may act. */
45 static int mi_can_breakpoint_notify;
47 /* Output a single breakpoint, when allowed. */
50 breakpoint_notify (struct breakpoint *b)
52 if (mi_can_breakpoint_notify)
53 gdb_breakpoint_query (current_uiout, b->number, NULL);
63 /* Arrange for all new breakpoints and catchpoints to be reported to
64 CURRENT_UIOUT until the cleanup returned by this function is run.
66 Note that MI output will be probably invalid if more than one
67 breakpoint is created inside one MI command. */
70 setup_breakpoint_reporting (void)
72 struct cleanup *rev_flag;
74 if (! mi_breakpoint_observers_installed)
76 observer_attach_breakpoint_created (breakpoint_notify);
77 mi_breakpoint_observers_installed = 1;
80 rev_flag = make_cleanup_restore_integer (&mi_can_breakpoint_notify);
81 mi_can_breakpoint_notify = 1;
87 /* Implements the -break-insert command.
88 See the MI manual for the list of possible options. */
91 mi_cmd_break_insert (char *command, char **argv, int argc)
98 char *condition = NULL;
102 struct cleanup *back_to;
103 enum bptype type_wanted;
104 struct breakpoint_ops *ops;
108 HARDWARE_OPT, TEMP_OPT, CONDITION_OPT,
109 IGNORE_COUNT_OPT, THREAD_OPT, PENDING_OPT, DISABLE_OPT,
112 static const struct mi_opt opts[] =
114 {"h", HARDWARE_OPT, 0},
116 {"c", CONDITION_OPT, 1},
117 {"i", IGNORE_COUNT_OPT, 1},
118 {"p", THREAD_OPT, 1},
119 {"f", PENDING_OPT, 0},
120 {"d", DISABLE_OPT, 0},
121 {"a", TRACEPOINT_OPT, 0},
125 /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
126 to denote the end of the option list. */
132 int opt = mi_getopt ("-break-insert", argc, argv,
136 switch ((enum opt) opt)
147 case IGNORE_COUNT_OPT:
148 ignore_count = atol (oarg);
151 thread = atol (oarg);
166 error (_("-break-insert: Missing <location>"));
168 error (_("-break-insert: Garbage following <location>"));
169 address = argv[oind];
171 /* Now we have what we need, let's insert the breakpoint! */
172 back_to = setup_breakpoint_reporting ();
174 /* Note that to request a fast tracepoint, the client uses the
175 "hardware" flag, although there's nothing of hardware related to
176 fast tracepoints -- one can implement slow tracepoints with
177 hardware breakpoints, but fast tracepoints are always software.
178 "fast" is a misnomer, actually, "jump" would be more appropriate.
179 A simulator or an emulator could conceivably implement fast
180 regular non-jump based tracepoints. */
181 type_wanted = (tracepoint
182 ? (hardware ? bp_fast_tracepoint : bp_tracepoint)
183 : (hardware ? bp_hardware_breakpoint : bp_breakpoint));
184 ops = tracepoint ? &tracepoint_breakpoint_ops : &bkpt_breakpoint_ops;
186 create_breakpoint (get_current_arch (), address, condition, thread,
188 0 /* condition and thread are valid. */,
191 pending ? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE,
192 ops, 0, enabled, 0, 0);
193 do_cleanups (back_to);
205 mi_cmd_break_passcount (char *command, char **argv, int argc)
209 struct tracepoint *t;
212 error (_("Usage: tracepoint-number passcount"));
216 t = get_tracepoint (n);
221 observer_notify_breakpoint_modified (&t->base);
225 error (_("Could not find tracepoint %d"), n);
229 /* Insert a watchpoint. The type of watchpoint is specified by the
231 -break-watch <expr> --> insert a regular wp.
232 -break-watch -r <expr> --> insert a read watchpoint.
233 -break-watch -a <expr> --> insert an access wp. */
236 mi_cmd_break_watch (char *command, char **argv, int argc)
239 enum wp_type type = REG_WP;
244 static const struct mi_opt opts[] =
247 {"a", ACCESS_OPT, 0},
251 /* Parse arguments. */
257 int opt = mi_getopt ("-break-watch", argc, argv,
262 switch ((enum opt) opt)
273 error (_("-break-watch: Missing <expression>"));
275 error (_("-break-watch: Garbage following <expression>"));
278 /* Now we have what we need, let's insert the watchpoint! */
282 watch_command_wrapper (expr, FROM_TTY, 0);
285 rwatch_command_wrapper (expr, FROM_TTY, 0);
288 awatch_command_wrapper (expr, FROM_TTY, 0);
291 error (_("-break-watch: Unknown watchpoint type."));
295 /* The mi_read_next_line consults these variable to return successive
296 command lines. While it would be clearer to use a closure pointer,
297 it is not expected that any future code will use read_command_lines_1,
298 therefore no point of overengineering. */
300 static char **mi_command_line_array;
301 static int mi_command_line_array_cnt;
302 static int mi_command_line_array_ptr;
305 mi_read_next_line (void)
307 if (mi_command_line_array_ptr == mi_command_line_array_cnt)
310 return mi_command_line_array[mi_command_line_array_ptr++];
314 mi_cmd_break_commands (char *command, char **argv, int argc)
316 struct command_line *break_command;
319 struct breakpoint *b;
322 error (_("USAGE: %s <BKPT> [<COMMAND> [<COMMAND>...]]"), command);
324 bnum = strtol (argv[0], &endptr, 0);
325 if (endptr == argv[0])
326 error (_("breakpoint number argument \"%s\" is not a number."),
328 else if (*endptr != '\0')
329 error (_("junk at the end of breakpoint number argument \"%s\"."),
332 b = get_breakpoint (bnum);
334 error (_("breakpoint %d not found."), bnum);
336 mi_command_line_array = argv;
337 mi_command_line_array_ptr = 1;
338 mi_command_line_array_cnt = argc;
340 if (is_tracepoint (b))
341 break_command = read_command_lines_1 (mi_read_next_line, 1,
342 check_tracepoint_command, b);
344 break_command = read_command_lines_1 (mi_read_next_line, 1, 0, 0);
346 breakpoint_set_commands (b, break_command);