Fix ChangeLog entry missing a ':' char.
[deliverable/binutils-gdb.git] / gdb / mi / mi-cmd-break.c
CommitLineData
fb40c209 1/* MI Command Set - breakpoint and watchpoint commands.
28e7fd62 2 Copyright (C) 2000-2013 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"
26#include "gdb_string.h"
27#include "mi-getopt.h"
5b7f31a4 28#include "gdb.h"
98deb0da 29#include "exceptions.h"
383f836e 30#include "observer.h"
8d3788bd 31#include "mi-main.h"
91985142 32#include "mi-cmd-break.h"
c5867ab6
HZ
33#include "gdb_obstack.h"
34#include <ctype.h>
fb40c209 35
fb40c209
AC
36enum
37 {
38 FROM_TTY = 0
39 };
40
383f836e
TT
41/* True if MI breakpoint observers have been registered. */
42
43static int mi_breakpoint_observers_installed;
44
45/* Control whether breakpoint_notify may act. */
46
47static int mi_can_breakpoint_notify;
48
2b03b41d 49/* Output a single breakpoint, when allowed. */
fb40c209
AC
50
51static void
8d3788bd 52breakpoint_notify (struct breakpoint *b)
fb40c209 53{
383f836e 54 if (mi_can_breakpoint_notify)
79a45e25 55 gdb_breakpoint_query (current_uiout, b->number, NULL);
fb40c209
AC
56}
57
fb40c209
AC
58enum bp_type
59 {
60 REG_BP,
61 HW_BP,
62 REGEXP_BP
63 };
64
91985142
MG
65/* Arrange for all new breakpoints and catchpoints to be reported to
66 CURRENT_UIOUT until the cleanup returned by this function is run.
67
68 Note that MI output will be probably invalid if more than one
69 breakpoint is created inside one MI command. */
70
71struct cleanup *
72setup_breakpoint_reporting (void)
73{
74 struct cleanup *rev_flag;
75
76 if (! mi_breakpoint_observers_installed)
77 {
78 observer_attach_breakpoint_created (breakpoint_notify);
79 mi_breakpoint_observers_installed = 1;
80 }
81
82 rev_flag = make_cleanup_restore_integer (&mi_can_breakpoint_notify);
83 mi_can_breakpoint_notify = 1;
84
85 return rev_flag;
86}
87
88
c5867ab6
HZ
89/* Convert arguments in ARGV to the string in "format",argv,argv...
90 and return it. */
fb40c209 91
c5867ab6
HZ
92static char *
93mi_argv_to_format (char **argv, int argc)
94{
95 int i;
96 struct obstack obstack;
97 char *ret;
98
99 obstack_init (&obstack);
100
101 /* Convert ARGV[OIND + 1] to format string and save to FORMAT. */
102 obstack_1grow (&obstack, '\"');
103 for (i = 0; i < strlen (argv[0]); i++)
104 {
105 switch (argv[0][i])
106 {
107 case '\\':
108 obstack_grow (&obstack, "\\\\", 2);
109 break;
110 case '\a':
111 obstack_grow (&obstack, "\\a", 2);
112 break;
113 case '\b':
114 obstack_grow (&obstack, "\\b", 2);
115 break;
116 case '\f':
117 obstack_grow (&obstack, "\\f", 2);
118 break;
119 case '\n':
120 obstack_grow (&obstack, "\\n", 2);
121 break;
122 case '\r':
123 obstack_grow (&obstack, "\\r", 2);
124 break;
125 case '\t':
126 obstack_grow (&obstack, "\\t", 2);
127 break;
128 case '\v':
129 obstack_grow (&obstack, "\\v", 2);
130 break;
fa876972
HZ
131 case '"':
132 obstack_grow (&obstack, "\\\"", 2);
133 break;
c5867ab6
HZ
134 default:
135 if (isprint (argv[0][i]))
136 obstack_grow (&obstack, argv[0] + i, 1);
137 else
138 {
139 char tmp[5];
140
ce70887a
JB
141 xsnprintf (tmp, sizeof (tmp), "\\%o",
142 (unsigned char) argv[0][i]);
c5867ab6
HZ
143 obstack_grow (&obstack, tmp, strlen (tmp));
144 }
145 break;
146 }
147 }
148 obstack_1grow (&obstack, '\"');
149
150 /* Apply other argv to FORMAT. */
151 for (i = 1; i < argc; i++)
152 {
153 obstack_1grow (&obstack, ',');
154 obstack_grow (&obstack, argv[i], strlen (argv[i]));
155 }
156 obstack_1grow (&obstack, '\0');
157
158 ret = xstrdup (obstack_finish (&obstack));
159 obstack_free (&obstack, NULL);
160
161 return ret;
162}
163
164/* Insert breakpoint.
165 If dprintf is true, it will insert dprintf.
166 If not, it will insert other type breakpoint. */
167
168static void
169mi_cmd_break_insert_1 (int dprintf, char *command, char **argv, int argc)
fb40c209
AC
170{
171 char *address = NULL;
8cdf0e15 172 int hardware = 0;
fb40c209
AC
173 int temp_p = 0;
174 int thread = -1;
175 int ignore_count = 0;
176 char *condition = NULL;
afe8ab22 177 int pending = 0;
41447f92 178 int enabled = 1;
6534d786 179 int tracepoint = 0;
c5867ab6 180 struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
0fb4aa4b 181 enum bptype type_wanted;
19ca11c5 182 struct breakpoint_ops *ops;
c5867ab6 183 char *extra_string = NULL;
41447f92 184
fb40c209
AC
185 enum opt
186 {
8cdf0e15 187 HARDWARE_OPT, TEMP_OPT, CONDITION_OPT,
6534d786
VP
188 IGNORE_COUNT_OPT, THREAD_OPT, PENDING_OPT, DISABLE_OPT,
189 TRACEPOINT_OPT,
fb40c209 190 };
91174723 191 static const struct mi_opt opts[] =
fb40c209
AC
192 {
193 {"h", HARDWARE_OPT, 0},
194 {"t", TEMP_OPT, 0},
195 {"c", CONDITION_OPT, 1},
196 {"i", IGNORE_COUNT_OPT, 1},
197 {"p", THREAD_OPT, 1},
afe8ab22 198 {"f", PENDING_OPT, 0},
41447f92 199 {"d", DISABLE_OPT, 0},
6534d786 200 {"a", TRACEPOINT_OPT, 0},
d5d6fca5 201 { 0, 0, 0 }
fb40c209
AC
202 };
203
204 /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
205 to denote the end of the option list. */
f8c000a2
AS
206 int oind = 0;
207 char *oarg;
102040f0 208
fb40c209
AC
209 while (1)
210 {
1b05df00 211 int opt = mi_getopt ("-break-insert", argc, argv,
f8c000a2 212 opts, &oind, &oarg);
fb40c209
AC
213 if (opt < 0)
214 break;
215 switch ((enum opt) opt)
216 {
217 case TEMP_OPT:
218 temp_p = 1;
219 break;
220 case HARDWARE_OPT:
8cdf0e15 221 hardware = 1;
fb40c209 222 break;
fb40c209 223 case CONDITION_OPT:
f8c000a2 224 condition = oarg;
fb40c209
AC
225 break;
226 case IGNORE_COUNT_OPT:
f8c000a2 227 ignore_count = atol (oarg);
fb40c209
AC
228 break;
229 case THREAD_OPT:
f8c000a2 230 thread = atol (oarg);
fb40c209 231 break;
afe8ab22
VP
232 case PENDING_OPT:
233 pending = 1;
234 break;
41447f92
VP
235 case DISABLE_OPT:
236 enabled = 0;
6534d786
VP
237 break;
238 case TRACEPOINT_OPT:
239 tracepoint = 1;
240 break;
fb40c209
AC
241 }
242 }
243
f8c000a2 244 if (oind >= argc)
c5867ab6
HZ
245 error (_("-%s-insert: Missing <location>"),
246 dprintf ? "dprintf" : "break");
f8c000a2 247 address = argv[oind];
c5867ab6
HZ
248 if (dprintf)
249 {
250 int format_num = oind + 1;
251
252 if (hardware || tracepoint)
253 error (_("-dprintf-insert: does not support -h or -a"));
254 if (format_num >= argc)
255 error (_("-dprintf-insert: Missing <format>"));
256
257 extra_string = mi_argv_to_format (argv + format_num, argc - format_num);
258 make_cleanup (xfree, extra_string);
259 }
260 else
261 {
262 if (oind < argc - 1)
263 error (_("-break-insert: Garbage following <location>"));
264 }
fb40c209 265
2b03b41d 266 /* Now we have what we need, let's insert the breakpoint! */
c5867ab6
HZ
267 setup_breakpoint_reporting ();
268
269 if (tracepoint)
270 {
271 /* Note that to request a fast tracepoint, the client uses the
272 "hardware" flag, although there's nothing of hardware related to
273 fast tracepoints -- one can implement slow tracepoints with
274 hardware breakpoints, but fast tracepoints are always software.
275 "fast" is a misnomer, actually, "jump" would be more appropriate.
276 A simulator or an emulator could conceivably implement fast
277 regular non-jump based tracepoints. */
278 type_wanted = hardware ? bp_fast_tracepoint : bp_tracepoint;
279 ops = &tracepoint_breakpoint_ops;
280 }
281 else if (dprintf)
282 {
283 type_wanted = bp_dprintf;
284 ops = &dprintf_breakpoint_ops;
285 }
286 else
287 {
288 type_wanted = hardware ? bp_hardware_breakpoint : bp_breakpoint;
289 ops = &bkpt_breakpoint_ops;
290 }
0fb4aa4b 291
8cdf0e15 292 create_breakpoint (get_current_arch (), address, condition, thread,
c5867ab6 293 extra_string,
8cdf0e15 294 0 /* condition and thread are valid. */,
0fb4aa4b 295 temp_p, type_wanted,
8cdf0e15
VP
296 ignore_count,
297 pending ? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE,
19ca11c5 298 ops, 0, enabled, 0, 0);
8cdf0e15 299 do_cleanups (back_to);
c5867ab6
HZ
300}
301
302/* Implements the -break-insert command.
303 See the MI manual for the list of possible options. */
8cdf0e15 304
c5867ab6
HZ
305void
306mi_cmd_break_insert (char *command, char **argv, int argc)
307{
308 mi_cmd_break_insert_1 (0, command, argv, argc);
309}
310
311/* Implements the -dprintf-insert command.
312 See the MI manual for the list of possible options. */
313
314void
315mi_cmd_dprintf_insert (char *command, char **argv, int argc)
316{
317 mi_cmd_break_insert_1 (1, command, argv, argc);
fb40c209
AC
318}
319
320enum wp_type
321{
322 REG_WP,
323 READ_WP,
324 ACCESS_WP
325};
326
9b4c786c
VP
327void
328mi_cmd_break_passcount (char *command, char **argv, int argc)
329{
330 int n;
331 int p;
d9b3f62e 332 struct tracepoint *t;
9b4c786c
VP
333
334 if (argc != 2)
335 error (_("Usage: tracepoint-number passcount"));
336
337 n = atoi (argv[0]);
338 p = atoi (argv[1]);
339 t = get_tracepoint (n);
340
341 if (t)
342 {
343 t->pass_count = p;
6f6484cd 344 observer_notify_breakpoint_modified (&t->base);
9b4c786c
VP
345 }
346 else
347 {
401a70b8 348 error (_("Could not find tracepoint %d"), n);
9b4c786c
VP
349 }
350}
351
fb40c209
AC
352/* Insert a watchpoint. The type of watchpoint is specified by the
353 first argument:
354 -break-watch <expr> --> insert a regular wp.
355 -break-watch -r <expr> --> insert a read watchpoint.
2b03b41d 356 -break-watch -a <expr> --> insert an access wp. */
fb40c209 357
ce8f13f8 358void
fb40c209
AC
359mi_cmd_break_watch (char *command, char **argv, int argc)
360{
361 char *expr = NULL;
362 enum wp_type type = REG_WP;
363 enum opt
364 {
365 READ_OPT, ACCESS_OPT
366 };
91174723 367 static const struct mi_opt opts[] =
fb40c209
AC
368 {
369 {"r", READ_OPT, 0},
370 {"a", ACCESS_OPT, 0},
d5d6fca5 371 { 0, 0, 0 }
fb40c209
AC
372 };
373
374 /* Parse arguments. */
f8c000a2
AS
375 int oind = 0;
376 char *oarg;
102040f0 377
fb40c209
AC
378 while (1)
379 {
1b05df00 380 int opt = mi_getopt ("-break-watch", argc, argv,
f8c000a2 381 opts, &oind, &oarg);
102040f0 382
fb40c209
AC
383 if (opt < 0)
384 break;
385 switch ((enum opt) opt)
386 {
387 case READ_OPT:
388 type = READ_WP;
389 break;
390 case ACCESS_OPT:
391 type = ACCESS_WP;
392 break;
393 }
394 }
f8c000a2 395 if (oind >= argc)
1b05df00 396 error (_("-break-watch: Missing <expression>"));
f8c000a2 397 if (oind < argc - 1)
1b05df00 398 error (_("-break-watch: Garbage following <expression>"));
f8c000a2 399 expr = argv[oind];
fb40c209 400
2b03b41d 401 /* Now we have what we need, let's insert the watchpoint! */
fb40c209
AC
402 switch (type)
403 {
404 case REG_WP:
84f4c1fe 405 watch_command_wrapper (expr, FROM_TTY, 0);
fb40c209
AC
406 break;
407 case READ_WP:
84f4c1fe 408 rwatch_command_wrapper (expr, FROM_TTY, 0);
fb40c209
AC
409 break;
410 case ACCESS_WP:
84f4c1fe 411 awatch_command_wrapper (expr, FROM_TTY, 0);
fb40c209
AC
412 break;
413 default:
1b05df00 414 error (_("-break-watch: Unknown watchpoint type."));
fb40c209 415 }
fb40c209 416}
48cb2d85
VP
417
418/* The mi_read_next_line consults these variable to return successive
419 command lines. While it would be clearer to use a closure pointer,
420 it is not expected that any future code will use read_command_lines_1,
421 therefore no point of overengineering. */
422
423static char **mi_command_line_array;
424static int mi_command_line_array_cnt;
425static int mi_command_line_array_ptr;
426
427static char *
a58d7472 428mi_read_next_line (void)
48cb2d85
VP
429{
430 if (mi_command_line_array_ptr == mi_command_line_array_cnt)
431 return NULL;
432 else
433 return mi_command_line_array[mi_command_line_array_ptr++];
434}
435
436void
437mi_cmd_break_commands (char *command, char **argv, int argc)
438{
439 struct command_line *break_command;
440 char *endptr;
441 int bnum;
442 struct breakpoint *b;
443
444 if (argc < 1)
9b20d036 445 error (_("USAGE: %s <BKPT> [<COMMAND> [<COMMAND>...]]"), command);
48cb2d85
VP
446
447 bnum = strtol (argv[0], &endptr, 0);
448 if (endptr == argv[0])
9b20d036 449 error (_("breakpoint number argument \"%s\" is not a number."),
48cb2d85
VP
450 argv[0]);
451 else if (*endptr != '\0')
9b20d036 452 error (_("junk at the end of breakpoint number argument \"%s\"."),
48cb2d85
VP
453 argv[0]);
454
455 b = get_breakpoint (bnum);
456 if (b == NULL)
9b20d036 457 error (_("breakpoint %d not found."), bnum);
48cb2d85
VP
458
459 mi_command_line_array = argv;
460 mi_command_line_array_ptr = 1;
461 mi_command_line_array_cnt = argc;
462
d77f58be 463 if (is_tracepoint (b))
a7bdde9e
VP
464 break_command = read_command_lines_1 (mi_read_next_line, 1,
465 check_tracepoint_command, b);
466 else
467 break_command = read_command_lines_1 (mi_read_next_line, 1, 0, 0);
468
48cb2d85
VP
469 breakpoint_set_commands (b, break_command);
470}
471
This page took 1.115588 seconds and 4 git commands to generate.