Upgrade GDB from 7.4.1 to 7.6.1 on the vendor branch
[dragonfly.git] / contrib / gdb-7 / gdb / mi / mi-cmd-break.c
CommitLineData
5796c8dc 1/* MI Command Set - breakpoint and watchpoint commands.
ef5ccd6c 2 Copyright (C) 2000-2013 Free Software Foundation, Inc.
5796c8dc
SS
3 Contributed by Cygnus Solutions (a Red Hat company).
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
9 the Free Software Foundation; either version 3 of the License, or
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
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20#include "defs.h"
21#include "arch-utils.h"
22#include "mi-cmds.h"
23#include "ui-out.h"
24#include "mi-out.h"
25#include "breakpoint.h"
26#include "gdb_string.h"
27#include "mi-getopt.h"
28#include "gdb.h"
29#include "exceptions.h"
30#include "observer.h"
a45ae5f8 31#include "mi-main.h"
ef5ccd6c 32#include "mi-cmd-break.h"
5796c8dc
SS
33
34enum
35 {
36 FROM_TTY = 0
37 };
38
39/* True if MI breakpoint observers have been registered. */
40
41static int mi_breakpoint_observers_installed;
42
43/* Control whether breakpoint_notify may act. */
44
45static int mi_can_breakpoint_notify;
46
ef5ccd6c 47/* Output a single breakpoint, when allowed. */
5796c8dc
SS
48
49static void
a45ae5f8 50breakpoint_notify (struct breakpoint *b)
5796c8dc
SS
51{
52 if (mi_can_breakpoint_notify)
a45ae5f8 53 gdb_breakpoint_query (current_uiout, b->number, NULL);
5796c8dc
SS
54}
55
56enum bp_type
57 {
58 REG_BP,
59 HW_BP,
60 REGEXP_BP
61 };
62
ef5ccd6c
JM
63/* Arrange for all new breakpoints and catchpoints to be reported to
64 CURRENT_UIOUT until the cleanup returned by this function is run.
65
66 Note that MI output will be probably invalid if more than one
67 breakpoint is created inside one MI command. */
68
69struct cleanup *
70setup_breakpoint_reporting (void)
71{
72 struct cleanup *rev_flag;
73
74 if (! mi_breakpoint_observers_installed)
75 {
76 observer_attach_breakpoint_created (breakpoint_notify);
77 mi_breakpoint_observers_installed = 1;
78 }
79
80 rev_flag = make_cleanup_restore_integer (&mi_can_breakpoint_notify);
81 mi_can_breakpoint_notify = 1;
82
83 return rev_flag;
84}
85
86
5796c8dc
SS
87/* Implements the -break-insert command.
88 See the MI manual for the list of possible options. */
89
90void
91mi_cmd_break_insert (char *command, char **argv, int argc)
92{
93 char *address = NULL;
cf7f2e2d 94 int hardware = 0;
5796c8dc
SS
95 int temp_p = 0;
96 int thread = -1;
97 int ignore_count = 0;
98 char *condition = NULL;
99 int pending = 0;
100 int enabled = 1;
cf7f2e2d
JM
101 int tracepoint = 0;
102 struct cleanup *back_to;
103 enum bptype type_wanted;
ef5ccd6c 104 struct breakpoint_ops *ops;
5796c8dc 105
5796c8dc
SS
106 enum opt
107 {
cf7f2e2d
JM
108 HARDWARE_OPT, TEMP_OPT, CONDITION_OPT,
109 IGNORE_COUNT_OPT, THREAD_OPT, PENDING_OPT, DISABLE_OPT,
110 TRACEPOINT_OPT,
5796c8dc 111 };
a45ae5f8 112 static const struct mi_opt opts[] =
5796c8dc
SS
113 {
114 {"h", HARDWARE_OPT, 0},
115 {"t", TEMP_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},
cf7f2e2d 121 {"a", TRACEPOINT_OPT, 0},
5796c8dc
SS
122 { 0, 0, 0 }
123 };
124
125 /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
126 to denote the end of the option list. */
ef5ccd6c
JM
127 int oind = 0;
128 char *oarg;
cf7f2e2d 129
5796c8dc
SS
130 while (1)
131 {
c50c785c 132 int opt = mi_getopt ("-break-insert", argc, argv,
ef5ccd6c 133 opts, &oind, &oarg);
5796c8dc
SS
134 if (opt < 0)
135 break;
136 switch ((enum opt) opt)
137 {
138 case TEMP_OPT:
139 temp_p = 1;
140 break;
141 case HARDWARE_OPT:
cf7f2e2d 142 hardware = 1;
5796c8dc 143 break;
5796c8dc 144 case CONDITION_OPT:
ef5ccd6c 145 condition = oarg;
5796c8dc
SS
146 break;
147 case IGNORE_COUNT_OPT:
ef5ccd6c 148 ignore_count = atol (oarg);
5796c8dc
SS
149 break;
150 case THREAD_OPT:
ef5ccd6c 151 thread = atol (oarg);
5796c8dc
SS
152 break;
153 case PENDING_OPT:
154 pending = 1;
155 break;
156 case DISABLE_OPT:
157 enabled = 0;
cf7f2e2d
JM
158 break;
159 case TRACEPOINT_OPT:
160 tracepoint = 1;
161 break;
5796c8dc
SS
162 }
163 }
164
ef5ccd6c 165 if (oind >= argc)
c50c785c 166 error (_("-break-insert: Missing <location>"));
ef5ccd6c 167 if (oind < argc - 1)
c50c785c 168 error (_("-break-insert: Garbage following <location>"));
ef5ccd6c 169 address = argv[oind];
5796c8dc 170
ef5ccd6c
JM
171 /* Now we have what we need, let's insert the breakpoint! */
172 back_to = setup_breakpoint_reporting ();
cf7f2e2d
JM
173
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));
ef5ccd6c 184 ops = tracepoint ? &tracepoint_breakpoint_ops : &bkpt_breakpoint_ops;
cf7f2e2d
JM
185
186 create_breakpoint (get_current_arch (), address, condition, thread,
ef5ccd6c 187 NULL,
cf7f2e2d
JM
188 0 /* condition and thread are valid. */,
189 temp_p, type_wanted,
190 ignore_count,
191 pending ? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE,
ef5ccd6c 192 ops, 0, enabled, 0, 0);
cf7f2e2d
JM
193 do_cleanups (back_to);
194
5796c8dc
SS
195}
196
197enum wp_type
198{
199 REG_WP,
200 READ_WP,
201 ACCESS_WP
202};
203
cf7f2e2d
JM
204void
205mi_cmd_break_passcount (char *command, char **argv, int argc)
206{
207 int n;
208 int p;
a45ae5f8 209 struct tracepoint *t;
cf7f2e2d
JM
210
211 if (argc != 2)
212 error (_("Usage: tracepoint-number passcount"));
213
214 n = atoi (argv[0]);
215 p = atoi (argv[1]);
216 t = get_tracepoint (n);
217
218 if (t)
219 {
220 t->pass_count = p;
ef5ccd6c 221 observer_notify_breakpoint_modified (&t->base);
cf7f2e2d
JM
222 }
223 else
224 {
a45ae5f8 225 error (_("Could not find tracepoint %d"), n);
cf7f2e2d
JM
226 }
227}
228
5796c8dc
SS
229/* Insert a watchpoint. The type of watchpoint is specified by the
230 first argument:
231 -break-watch <expr> --> insert a regular wp.
232 -break-watch -r <expr> --> insert a read watchpoint.
ef5ccd6c 233 -break-watch -a <expr> --> insert an access wp. */
5796c8dc
SS
234
235void
236mi_cmd_break_watch (char *command, char **argv, int argc)
237{
238 char *expr = NULL;
239 enum wp_type type = REG_WP;
240 enum opt
241 {
242 READ_OPT, ACCESS_OPT
243 };
a45ae5f8 244 static const struct mi_opt opts[] =
5796c8dc
SS
245 {
246 {"r", READ_OPT, 0},
247 {"a", ACCESS_OPT, 0},
248 { 0, 0, 0 }
249 };
250
251 /* Parse arguments. */
ef5ccd6c
JM
252 int oind = 0;
253 char *oarg;
cf7f2e2d 254
5796c8dc
SS
255 while (1)
256 {
c50c785c 257 int opt = mi_getopt ("-break-watch", argc, argv,
ef5ccd6c 258 opts, &oind, &oarg);
cf7f2e2d 259
5796c8dc
SS
260 if (opt < 0)
261 break;
262 switch ((enum opt) opt)
263 {
264 case READ_OPT:
265 type = READ_WP;
266 break;
267 case ACCESS_OPT:
268 type = ACCESS_WP;
269 break;
270 }
271 }
ef5ccd6c 272 if (oind >= argc)
c50c785c 273 error (_("-break-watch: Missing <expression>"));
ef5ccd6c 274 if (oind < argc - 1)
c50c785c 275 error (_("-break-watch: Garbage following <expression>"));
ef5ccd6c 276 expr = argv[oind];
5796c8dc 277
ef5ccd6c 278 /* Now we have what we need, let's insert the watchpoint! */
5796c8dc
SS
279 switch (type)
280 {
281 case REG_WP:
c50c785c 282 watch_command_wrapper (expr, FROM_TTY, 0);
5796c8dc
SS
283 break;
284 case READ_WP:
c50c785c 285 rwatch_command_wrapper (expr, FROM_TTY, 0);
5796c8dc
SS
286 break;
287 case ACCESS_WP:
c50c785c 288 awatch_command_wrapper (expr, FROM_TTY, 0);
5796c8dc
SS
289 break;
290 default:
c50c785c 291 error (_("-break-watch: Unknown watchpoint type."));
5796c8dc
SS
292 }
293}
294
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. */
299
300static char **mi_command_line_array;
301static int mi_command_line_array_cnt;
302static int mi_command_line_array_ptr;
303
304static char *
cf7f2e2d 305mi_read_next_line (void)
5796c8dc
SS
306{
307 if (mi_command_line_array_ptr == mi_command_line_array_cnt)
308 return NULL;
309 else
310 return mi_command_line_array[mi_command_line_array_ptr++];
311}
312
313void
314mi_cmd_break_commands (char *command, char **argv, int argc)
315{
316 struct command_line *break_command;
317 char *endptr;
318 int bnum;
319 struct breakpoint *b;
320
321 if (argc < 1)
c50c785c 322 error (_("USAGE: %s <BKPT> [<COMMAND> [<COMMAND>...]]"), command);
5796c8dc
SS
323
324 bnum = strtol (argv[0], &endptr, 0);
325 if (endptr == argv[0])
c50c785c 326 error (_("breakpoint number argument \"%s\" is not a number."),
5796c8dc
SS
327 argv[0]);
328 else if (*endptr != '\0')
c50c785c 329 error (_("junk at the end of breakpoint number argument \"%s\"."),
5796c8dc
SS
330 argv[0]);
331
332 b = get_breakpoint (bnum);
333 if (b == NULL)
c50c785c 334 error (_("breakpoint %d not found."), bnum);
5796c8dc
SS
335
336 mi_command_line_array = argv;
337 mi_command_line_array_ptr = 1;
338 mi_command_line_array_cnt = argc;
339
cf7f2e2d
JM
340 if (is_tracepoint (b))
341 break_command = read_command_lines_1 (mi_read_next_line, 1,
342 check_tracepoint_command, b);
343 else
344 break_command = read_command_lines_1 (mi_read_next_line, 1, 0, 0);
345
5796c8dc
SS
346 breakpoint_set_commands (b, break_command);
347}
348