Update year range in copyright notice of all files owned by the GDB project.
[deliverable/binutils-gdb.git] / gdb / mi / mi-cmd-break.c
1 /* MI Command Set - breakpoint and watchpoint commands.
2 Copyright (C) 2000-2015 Free Software Foundation, Inc.
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 "mi-getopt.h"
27 #include "gdb.h"
28 #include "observer.h"
29 #include "mi-main.h"
30 #include "mi-cmd-break.h"
31 #include "gdb_obstack.h"
32 #include <ctype.h>
33
34 enum
35 {
36 FROM_TTY = 0
37 };
38
39 /* True if MI breakpoint observers have been registered. */
40
41 static int mi_breakpoint_observers_installed;
42
43 /* Control whether breakpoint_notify may act. */
44
45 static int mi_can_breakpoint_notify;
46
47 /* Output a single breakpoint, when allowed. */
48
49 static void
50 breakpoint_notify (struct breakpoint *b)
51 {
52 if (mi_can_breakpoint_notify)
53 gdb_breakpoint_query (current_uiout, b->number, NULL);
54 }
55
56 enum bp_type
57 {
58 REG_BP,
59 HW_BP,
60 REGEXP_BP
61 };
62
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
69 struct cleanup *
70 setup_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
87 /* Convert arguments in ARGV to the string in "format",argv,argv...
88 and return it. */
89
90 static char *
91 mi_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;
129 case '"':
130 obstack_grow (&obstack, "\\\"", 2);
131 break;
132 default:
133 if (isprint (argv[0][i]))
134 obstack_grow (&obstack, argv[0] + i, 1);
135 else
136 {
137 char tmp[5];
138
139 xsnprintf (tmp, sizeof (tmp), "\\%o",
140 (unsigned char) argv[0][i]);
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
166 static void
167 mi_cmd_break_insert_1 (int dprintf, char *command, char **argv, int argc)
168 {
169 char *address = NULL;
170 int hardware = 0;
171 int temp_p = 0;
172 int thread = -1;
173 int ignore_count = 0;
174 char *condition = NULL;
175 int pending = 0;
176 int enabled = 1;
177 int tracepoint = 0;
178 struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
179 enum bptype type_wanted;
180 struct breakpoint_ops *ops;
181 char *extra_string = NULL;
182
183 enum opt
184 {
185 HARDWARE_OPT, TEMP_OPT, CONDITION_OPT,
186 IGNORE_COUNT_OPT, THREAD_OPT, PENDING_OPT, DISABLE_OPT,
187 TRACEPOINT_OPT,
188 };
189 static const struct mi_opt opts[] =
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},
196 {"f", PENDING_OPT, 0},
197 {"d", DISABLE_OPT, 0},
198 {"a", TRACEPOINT_OPT, 0},
199 { 0, 0, 0 }
200 };
201
202 /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
203 to denote the end of the option list. */
204 int oind = 0;
205 char *oarg;
206
207 while (1)
208 {
209 int opt = mi_getopt ("-break-insert", argc, argv,
210 opts, &oind, &oarg);
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:
219 hardware = 1;
220 break;
221 case CONDITION_OPT:
222 condition = oarg;
223 break;
224 case IGNORE_COUNT_OPT:
225 ignore_count = atol (oarg);
226 break;
227 case THREAD_OPT:
228 thread = atol (oarg);
229 break;
230 case PENDING_OPT:
231 pending = 1;
232 break;
233 case DISABLE_OPT:
234 enabled = 0;
235 break;
236 case TRACEPOINT_OPT:
237 tracepoint = 1;
238 break;
239 }
240 }
241
242 if (oind >= argc)
243 error (_("-%s-insert: Missing <location>"),
244 dprintf ? "dprintf" : "break");
245 address = argv[oind];
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 }
263
264 /* Now we have what we need, let's insert the breakpoint! */
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 }
289
290 create_breakpoint (get_current_arch (), address, condition, thread,
291 extra_string,
292 0 /* condition and thread are valid. */,
293 temp_p, type_wanted,
294 ignore_count,
295 pending ? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE,
296 ops, 0, enabled, 0, 0);
297 do_cleanups (back_to);
298 }
299
300 /* Implements the -break-insert command.
301 See the MI manual for the list of possible options. */
302
303 void
304 mi_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
312 void
313 mi_cmd_dprintf_insert (char *command, char **argv, int argc)
314 {
315 mi_cmd_break_insert_1 (1, command, argv, argc);
316 }
317
318 enum wp_type
319 {
320 REG_WP,
321 READ_WP,
322 ACCESS_WP
323 };
324
325 void
326 mi_cmd_break_passcount (char *command, char **argv, int argc)
327 {
328 int n;
329 int p;
330 struct tracepoint *t;
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;
342 observer_notify_breakpoint_modified (&t->base);
343 }
344 else
345 {
346 error (_("Could not find tracepoint %d"), n);
347 }
348 }
349
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.
354 -break-watch -a <expr> --> insert an access wp. */
355
356 void
357 mi_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 };
365 static const struct mi_opt opts[] =
366 {
367 {"r", READ_OPT, 0},
368 {"a", ACCESS_OPT, 0},
369 { 0, 0, 0 }
370 };
371
372 /* Parse arguments. */
373 int oind = 0;
374 char *oarg;
375
376 while (1)
377 {
378 int opt = mi_getopt ("-break-watch", argc, argv,
379 opts, &oind, &oarg);
380
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 }
393 if (oind >= argc)
394 error (_("-break-watch: Missing <expression>"));
395 if (oind < argc - 1)
396 error (_("-break-watch: Garbage following <expression>"));
397 expr = argv[oind];
398
399 /* Now we have what we need, let's insert the watchpoint! */
400 switch (type)
401 {
402 case REG_WP:
403 watch_command_wrapper (expr, FROM_TTY, 0);
404 break;
405 case READ_WP:
406 rwatch_command_wrapper (expr, FROM_TTY, 0);
407 break;
408 case ACCESS_WP:
409 awatch_command_wrapper (expr, FROM_TTY, 0);
410 break;
411 default:
412 error (_("-break-watch: Unknown watchpoint type."));
413 }
414 }
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
421 static char **mi_command_line_array;
422 static int mi_command_line_array_cnt;
423 static int mi_command_line_array_ptr;
424
425 static char *
426 mi_read_next_line (void)
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
434 void
435 mi_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)
443 error (_("USAGE: %s <BKPT> [<COMMAND> [<COMMAND>...]]"), command);
444
445 bnum = strtol (argv[0], &endptr, 0);
446 if (endptr == argv[0])
447 error (_("breakpoint number argument \"%s\" is not a number."),
448 argv[0]);
449 else if (*endptr != '\0')
450 error (_("junk at the end of breakpoint number argument \"%s\"."),
451 argv[0]);
452
453 b = get_breakpoint (bnum);
454 if (b == NULL)
455 error (_("breakpoint %d not found."), bnum);
456
457 mi_command_line_array = argv;
458 mi_command_line_array_ptr = 1;
459 mi_command_line_array_cnt = argc;
460
461 if (is_tracepoint (b))
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
467 breakpoint_set_commands (b, break_command);
468 }
469
This page took 0.049914 seconds and 5 git commands to generate.