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