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