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