2011-01-05 Michael Snyder <msnyder@vmware.com>
[deliverable/binutils-gdb.git] / gdb / mi / mi-cmd-break.c
CommitLineData
fb40c209 1/* MI Command Set - breakpoint and watchpoint commands.
7b6bb8da 2 Copyright (C) 2000, 2001, 2002, 2007, 2008, 2009, 2010, 2011
0fb0cc75 3 Free Software Foundation, Inc.
ab91fdd5 4 Contributed by Cygnus Solutions (a Red Hat company).
fb40c209
AC
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
fb40c209
AC
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
fb40c209
AC
20
21#include "defs.h"
a6d9a66e 22#include "arch-utils.h"
fb40c209
AC
23#include "mi-cmds.h"
24#include "ui-out.h"
25#include "mi-out.h"
26#include "breakpoint.h"
27#include "gdb_string.h"
28#include "mi-getopt.h"
5b7f31a4 29#include "gdb.h"
98deb0da 30#include "exceptions.h"
383f836e 31#include "observer.h"
fb40c209 32
fb40c209
AC
33enum
34 {
35 FROM_TTY = 0
36 };
37
383f836e
TT
38/* True if MI breakpoint observers have been registered. */
39
40static int mi_breakpoint_observers_installed;
41
42/* Control whether breakpoint_notify may act. */
43
44static int mi_can_breakpoint_notify;
45
46/* Output a single breakpoint, when allowed. */
fb40c209
AC
47
48static void
49breakpoint_notify (int b)
50{
383f836e
TT
51 if (mi_can_breakpoint_notify)
52 gdb_breakpoint_query (uiout, b, NULL);
fb40c209
AC
53}
54
fb40c209
AC
55enum bp_type
56 {
57 REG_BP,
58 HW_BP,
59 REGEXP_BP
60 };
61
afe8ab22
VP
62/* Implements the -break-insert command.
63 See the MI manual for the list of possible options. */
fb40c209 64
ce8f13f8 65void
fb40c209
AC
66mi_cmd_break_insert (char *command, char **argv, int argc)
67{
68 char *address = NULL;
8cdf0e15 69 int hardware = 0;
fb40c209
AC
70 int temp_p = 0;
71 int thread = -1;
72 int ignore_count = 0;
73 char *condition = NULL;
afe8ab22 74 int pending = 0;
41447f92 75 int enabled = 1;
6534d786 76 int tracepoint = 0;
8cdf0e15 77 struct cleanup *back_to;
0fb4aa4b 78 enum bptype type_wanted;
41447f92 79
fb40c209
AC
80 enum opt
81 {
8cdf0e15 82 HARDWARE_OPT, TEMP_OPT, CONDITION_OPT,
6534d786
VP
83 IGNORE_COUNT_OPT, THREAD_OPT, PENDING_OPT, DISABLE_OPT,
84 TRACEPOINT_OPT,
fb40c209
AC
85 };
86 static struct mi_opt opts[] =
87 {
88 {"h", HARDWARE_OPT, 0},
89 {"t", TEMP_OPT, 0},
90 {"c", CONDITION_OPT, 1},
91 {"i", IGNORE_COUNT_OPT, 1},
92 {"p", THREAD_OPT, 1},
afe8ab22 93 {"f", PENDING_OPT, 0},
41447f92 94 {"d", DISABLE_OPT, 0},
6534d786 95 {"a", TRACEPOINT_OPT, 0},
d5d6fca5 96 { 0, 0, 0 }
fb40c209
AC
97 };
98
99 /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
100 to denote the end of the option list. */
101 int optind = 0;
102 char *optarg;
102040f0 103
fb40c209
AC
104 while (1)
105 {
9a2b4c1b
MS
106 int opt = mi_getopt ("mi_cmd_break_insert", argc, argv,
107 opts, &optind, &optarg);
fb40c209
AC
108 if (opt < 0)
109 break;
110 switch ((enum opt) opt)
111 {
112 case TEMP_OPT:
113 temp_p = 1;
114 break;
115 case HARDWARE_OPT:
8cdf0e15 116 hardware = 1;
fb40c209 117 break;
fb40c209
AC
118 case CONDITION_OPT:
119 condition = optarg;
120 break;
121 case IGNORE_COUNT_OPT:
122 ignore_count = atol (optarg);
123 break;
124 case THREAD_OPT:
125 thread = atol (optarg);
126 break;
afe8ab22
VP
127 case PENDING_OPT:
128 pending = 1;
129 break;
41447f92
VP
130 case DISABLE_OPT:
131 enabled = 0;
6534d786
VP
132 break;
133 case TRACEPOINT_OPT:
134 tracepoint = 1;
135 break;
fb40c209
AC
136 }
137 }
138
139 if (optind >= argc)
8a3fe4f8 140 error (_("mi_cmd_break_insert: Missing <location>"));
fb40c209 141 if (optind < argc - 1)
8a3fe4f8 142 error (_("mi_cmd_break_insert: Garbage following <location>"));
fb40c209
AC
143 address = argv[optind];
144
145 /* Now we have what we need, let's insert the breakpoint! */
383f836e
TT
146 if (! mi_breakpoint_observers_installed)
147 {
148 observer_attach_breakpoint_created (breakpoint_notify);
149 observer_attach_breakpoint_modified (breakpoint_notify);
150 observer_attach_breakpoint_deleted (breakpoint_notify);
151 mi_breakpoint_observers_installed = 1;
152 }
153
8cdf0e15 154 back_to = make_cleanup_restore_integer (&mi_can_breakpoint_notify);
383f836e 155 mi_can_breakpoint_notify = 1;
0fb4aa4b
PA
156
157 /* Note that to request a fast tracepoint, the client uses the
158 "hardware" flag, although there's nothing of hardware related to
159 fast tracepoints -- one can implement slow tracepoints with
160 hardware breakpoints, but fast tracepoints are always software.
161 "fast" is a misnomer, actually, "jump" would be more appropriate.
162 A simulator or an emulator could conceivably implement fast
163 regular non-jump based tracepoints. */
164 type_wanted = (tracepoint
165 ? (hardware ? bp_fast_tracepoint : bp_tracepoint)
166 : (hardware ? bp_hardware_breakpoint : bp_breakpoint));
167
8cdf0e15
VP
168 create_breakpoint (get_current_arch (), address, condition, thread,
169 0 /* condition and thread are valid. */,
0fb4aa4b 170 temp_p, type_wanted,
8cdf0e15
VP
171 ignore_count,
172 pending ? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE,
84f4c1fe 173 NULL, 0, enabled, 0);
8cdf0e15
VP
174 do_cleanups (back_to);
175
fb40c209
AC
176}
177
178enum wp_type
179{
180 REG_WP,
181 READ_WP,
182 ACCESS_WP
183};
184
9b4c786c
VP
185void
186mi_cmd_break_passcount (char *command, char **argv, int argc)
187{
188 int n;
189 int p;
190 struct breakpoint *t;
191
192 if (argc != 2)
193 error (_("Usage: tracepoint-number passcount"));
194
195 n = atoi (argv[0]);
196 p = atoi (argv[1]);
197 t = get_tracepoint (n);
198
199 if (t)
200 {
201 t->pass_count = p;
202 observer_notify_tracepoint_modified (n);
203 }
204 else
205 {
206 error (_("Cound not find tracepoint %d"), n);
207 }
208}
209
fb40c209
AC
210/* Insert a watchpoint. The type of watchpoint is specified by the
211 first argument:
212 -break-watch <expr> --> insert a regular wp.
213 -break-watch -r <expr> --> insert a read watchpoint.
214 -break-watch -a <expr> --> insert an access wp. */
215
ce8f13f8 216void
fb40c209
AC
217mi_cmd_break_watch (char *command, char **argv, int argc)
218{
219 char *expr = NULL;
220 enum wp_type type = REG_WP;
221 enum opt
222 {
223 READ_OPT, ACCESS_OPT
224 };
225 static struct mi_opt opts[] =
226 {
227 {"r", READ_OPT, 0},
228 {"a", ACCESS_OPT, 0},
d5d6fca5 229 { 0, 0, 0 }
fb40c209
AC
230 };
231
232 /* Parse arguments. */
233 int optind = 0;
234 char *optarg;
102040f0 235
fb40c209
AC
236 while (1)
237 {
102040f0
MS
238 int opt = mi_getopt ("mi_cmd_break_watch", argc, argv,
239 opts, &optind, &optarg);
240
fb40c209
AC
241 if (opt < 0)
242 break;
243 switch ((enum opt) opt)
244 {
245 case READ_OPT:
246 type = READ_WP;
247 break;
248 case ACCESS_OPT:
249 type = ACCESS_WP;
250 break;
251 }
252 }
253 if (optind >= argc)
8a3fe4f8 254 error (_("mi_cmd_break_watch: Missing <expression>"));
fb40c209 255 if (optind < argc - 1)
8a3fe4f8 256 error (_("mi_cmd_break_watch: Garbage following <expression>"));
fb40c209
AC
257 expr = argv[optind];
258
259 /* Now we have what we need, let's insert the watchpoint! */
260 switch (type)
261 {
262 case REG_WP:
84f4c1fe 263 watch_command_wrapper (expr, FROM_TTY, 0);
fb40c209
AC
264 break;
265 case READ_WP:
84f4c1fe 266 rwatch_command_wrapper (expr, FROM_TTY, 0);
fb40c209
AC
267 break;
268 case ACCESS_WP:
84f4c1fe 269 awatch_command_wrapper (expr, FROM_TTY, 0);
fb40c209
AC
270 break;
271 default:
8a3fe4f8 272 error (_("mi_cmd_break_watch: Unknown watchpoint type."));
fb40c209 273 }
fb40c209 274}
48cb2d85
VP
275
276/* The mi_read_next_line consults these variable to return successive
277 command lines. While it would be clearer to use a closure pointer,
278 it is not expected that any future code will use read_command_lines_1,
279 therefore no point of overengineering. */
280
281static char **mi_command_line_array;
282static int mi_command_line_array_cnt;
283static int mi_command_line_array_ptr;
284
285static char *
a58d7472 286mi_read_next_line (void)
48cb2d85
VP
287{
288 if (mi_command_line_array_ptr == mi_command_line_array_cnt)
289 return NULL;
290 else
291 return mi_command_line_array[mi_command_line_array_ptr++];
292}
293
294void
295mi_cmd_break_commands (char *command, char **argv, int argc)
296{
297 struct command_line *break_command;
298 char *endptr;
299 int bnum;
300 struct breakpoint *b;
301
302 if (argc < 1)
303 error ("USAGE: %s <BKPT> [<COMMAND> [<COMMAND>...]]", command);
304
305 bnum = strtol (argv[0], &endptr, 0);
306 if (endptr == argv[0])
307 error ("breakpoint number argument \"%s\" is not a number.",
308 argv[0]);
309 else if (*endptr != '\0')
310 error ("junk at the end of breakpoint number argument \"%s\".",
311 argv[0]);
312
313 b = get_breakpoint (bnum);
314 if (b == NULL)
315 error ("breakpoint %d not found.", bnum);
316
317 mi_command_line_array = argv;
318 mi_command_line_array_ptr = 1;
319 mi_command_line_array_cnt = argc;
320
d77f58be 321 if (is_tracepoint (b))
a7bdde9e
VP
322 break_command = read_command_lines_1 (mi_read_next_line, 1,
323 check_tracepoint_command, b);
324 else
325 break_command = read_command_lines_1 (mi_read_next_line, 1, 0, 0);
326
48cb2d85
VP
327 breakpoint_set_commands (b, break_command);
328}
329
This page took 0.878912 seconds and 4 git commands to generate.