GDB (xrefs)
mi-cmd-break.c
Go to the documentation of this file.
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  {
37  };
38 
39 /* True if MI breakpoint observers have been registered. */
40 
42 
43 /* Control whether breakpoint_notify may act. */
44 
46 
47 /* Output a single breakpoint, when allowed. */
48 
49 static void
51 {
54 }
55 
56 enum bp_type
57  {
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 *
71 {
72  struct cleanup *rev_flag;
73 
75  {
78  }
79 
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! */
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;
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,
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 
319 {
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;
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;
424 
425 static char *
427 {
429  return NULL;
430  else
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;
460 
461  if (is_tracepoint (b))
462  break_command = read_command_lines_1 (mi_read_next_line, 1,
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 
void awatch_command_wrapper(char *arg, int from_tty, int internal)
Definition: breakpoint.c:11393
void mi_cmd_break_passcount(char *command, char **argv, int argc)
Definition: mi-cmd-break.c:326
void check_tracepoint_command(char *line, void *closure)
Definition: breakpoint.c:1312
struct cleanup * setup_breakpoint_reporting(void)
Definition: mi-cmd-break.c:70
void xfree(void *)
Definition: common-utils.c:97
static char * mi_argv_to_format(char **argv, int argc)
Definition: mi-cmd-break.c:91
struct command_line * read_command_lines_1(char *(*read_next_line_func)(void), int parse_commands, void(*validator)(char *, void *), void *closure)
Definition: cli-script.c:1306
static void breakpoint_notify(struct breakpoint *b)
Definition: mi-cmd-break.c:50
static char * mi_read_next_line(void)
Definition: mi-cmd-break.c:426
bp_type
Definition: mi-cmd-break.c:56
struct breakpoint base
Definition: breakpoint.h:858
struct breakpoint_ops dprintf_breakpoint_ops
Definition: breakpoint.c:319
struct tracepoint * get_tracepoint(int num)
Definition: breakpoint.c:15197
void rwatch_command_wrapper(char *arg, int from_tty, int internal)
Definition: breakpoint.c:11381
#define _(String)
Definition: gdb_locale.h:40
struct breakpoint_ops tracepoint_breakpoint_ops
Definition: breakpoint.c:13329
void null_cleanup(void *arg)
Definition: cleanups.c:295
void mi_cmd_dprintf_insert(char *command, char **argv, int argc)
Definition: mi-cmd-break.c:313
void breakpoint_set_commands(struct breakpoint *b, struct command_line *commands)
Definition: breakpoint.c:1261
int mi_getopt(const char *prefix, int argc, char **argv, const struct mi_opt *opts, int *oind, char **oarg)
Definition: mi-getopt.c:83
struct cleanup * make_cleanup_restore_integer(int *variable)
Definition: utils.c:292
static int mi_command_line_array_cnt
Definition: mi-cmd-break.c:422
void mi_cmd_break_commands(char *command, char **argv, int argc)
Definition: mi-cmd-break.c:435
struct observer * observer_attach_breakpoint_created(observer_breakpoint_created_ftype *f)
struct cleanup * make_cleanup(make_cleanup_ftype *function, void *arg)
Definition: cleanups.c:117
Definition: gdbtypes.h:749
struct gdbarch * get_current_arch(void)
Definition: arch-utils.c:781
int pass_count
Definition: breakpoint.h:866
struct breakpoint * get_breakpoint(int num)
Definition: breakpoint.c:774
struct breakpoint_ops bkpt_breakpoint_ops
Definition: breakpoint.c:313
bptype
Definition: breakpoint.h:51
static char ** mi_command_line_array
Definition: mi-cmd-break.c:421
static int mi_command_line_array_ptr
Definition: mi-cmd-break.c:423
int create_breakpoint(struct gdbarch *gdbarch, char *arg, char *cond_string, int thread, char *extra_string, int parse_arg, int tempflag, enum bptype type_wanted, int ignore_count, enum auto_boolean pending_break_support, const struct breakpoint_ops *ops, int from_tty, int enabled, int internal, unsigned flags)
Definition: breakpoint.c:9585
void break_command(char *arg, int from_tty)
Definition: breakpoint.c:9908
int xsnprintf(char *str, size_t size, const char *format,...)
Definition: common-utils.c:134
void watch_command_wrapper(char *arg, int from_tty, int internal)
Definition: breakpoint.c:11350
enum gdb_rc gdb_breakpoint_query(struct ui_out *uiout, int bnum, char **error_message)
Definition: breakpoint.c:6626
wp_type
Definition: mi-cmd-break.c:318
void mi_cmd_break_watch(char *command, char **argv, int argc)
Definition: mi-cmd-break.c:357
static void mi_cmd_break_insert_1(int dprintf, char *command, char **argv, int argc)
Definition: mi-cmd-break.c:167
static int mi_can_breakpoint_notify
Definition: mi-cmd-break.c:45
struct ui_out * current_uiout
Definition: ui-out.c:233
static int mi_breakpoint_observers_installed
Definition: mi-cmd-break.c:41
int is_tracepoint(const struct breakpoint *b)
Definition: breakpoint.c:1163
void error(const char *fmt,...)
Definition: errors.c:38
void do_cleanups(struct cleanup *old_chain)
Definition: cleanups.c:175
void mi_cmd_break_insert(char *command, char **argv, int argc)
Definition: mi-cmd-break.c:304
void observer_notify_breakpoint_modified(struct breakpoint *b)