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-2018 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 "observer.h"
28 #include "mi-main.h"
29 #include "mi-cmd-break.h"
30 #include "language.h"
31 #include "location.h"
32 #include "linespec.h"
33 #include "gdb_obstack.h"
34 #include <ctype.h>
35 
36 enum
37  {
39  };
40 
41 /* True if MI breakpoint observers have been registered. */
42 
44 
45 /* Control whether breakpoint_notify may act. */
46 
48 
49 /* Output a single breakpoint, when allowed. */
50 
51 static void
53 {
55  {
56  TRY
57  {
58  print_breakpoint (b);
59  }
61  {
63  }
64  END_CATCH
65  }
66 }
67 
68 enum bp_type
69  {
73  };
74 
75 /* Arrange for all new breakpoints and catchpoints to be reported to
76  CURRENT_UIOUT until the destructor of the returned scoped_restore
77  is run.
78 
79  Note that MI output will be probably invalid if more than one
80  breakpoint is created inside one MI command. */
81 
84 {
86  {
89  }
90 
92 }
93 
94 
95 /* Convert arguments in ARGV to the string in "format",argv,argv...
96  and return it. */
97 
98 static std::string
99 mi_argv_to_format (char **argv, int argc)
100 {
101  int i;
102  std::string result;
103 
104  /* Convert ARGV[OIND + 1] to format string and save to FORMAT. */
105  result += '\"';
106  for (i = 0; i < strlen (argv[0]); i++)
107  {
108  switch (argv[0][i])
109  {
110  case '\\':
111  result += "\\\\";
112  break;
113  case '\a':
114  result += "\\a";
115  break;
116  case '\b':
117  result += "\\b";
118  break;
119  case '\f':
120  result += "\\f";
121  break;
122  case '\n':
123  result += "\\n";
124  break;
125  case '\r':
126  result += "\\r";
127  break;
128  case '\t':
129  result += "\\t";
130  break;
131  case '\v':
132  result += "\\v";
133  break;
134  case '"':
135  result += "\\\"";
136  break;
137  default:
138  if (isprint (argv[0][i]))
139  result += argv[0][i];
140  else
141  {
142  char tmp[5];
143 
144  xsnprintf (tmp, sizeof (tmp), "\\%o",
145  (unsigned char) argv[0][i]);
146  result += tmp;
147  }
148  break;
149  }
150  }
151  result += '\"';
152 
153  /* Apply other argv to FORMAT. */
154  for (i = 1; i < argc; i++)
155  {
156  result += ',';
157  result += argv[i];
158  }
159 
160  return result;
161 }
162 
163 /* Insert breakpoint.
164  If dprintf is true, it will insert dprintf.
165  If not, it will insert other type breakpoint. */
166 
167 static void
168 mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc)
169 {
170  const char *address = NULL;
171  int hardware = 0;
172  int temp_p = 0;
173  int thread = -1;
174  int ignore_count = 0;
175  char *condition = NULL;
176  int pending = 0;
177  int enabled = 1;
178  int tracepoint = 0;
179  enum bptype type_wanted;
181  struct breakpoint_ops *ops;
182  int is_explicit = 0;
183  struct explicit_location explicit_loc;
184  std::string extra_string;
185 
186  enum opt
187  {
188  HARDWARE_OPT, TEMP_OPT, CONDITION_OPT,
189  IGNORE_COUNT_OPT, THREAD_OPT, PENDING_OPT, DISABLE_OPT,
190  TRACEPOINT_OPT,
191  EXPLICIT_SOURCE_OPT, EXPLICIT_FUNC_OPT,
192  EXPLICIT_LABEL_OPT, EXPLICIT_LINE_OPT
193  };
194  static const struct mi_opt opts[] =
195  {
196  {"h", HARDWARE_OPT, 0},
197  {"t", TEMP_OPT, 0},
198  {"c", CONDITION_OPT, 1},
199  {"i", IGNORE_COUNT_OPT, 1},
200  {"p", THREAD_OPT, 1},
201  {"f", PENDING_OPT, 0},
202  {"d", DISABLE_OPT, 0},
203  {"a", TRACEPOINT_OPT, 0},
204  {"-source" , EXPLICIT_SOURCE_OPT, 1},
205  {"-function", EXPLICIT_FUNC_OPT, 1},
206  {"-label", EXPLICIT_LABEL_OPT, 1},
207  {"-line", EXPLICIT_LINE_OPT, 1},
208  { 0, 0, 0 }
209  };
210 
211  /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
212  to denote the end of the option list. */
213  int oind = 0;
214  char *oarg;
215 
216  initialize_explicit_location (&explicit_loc);
217 
218  while (1)
219  {
220  int opt = mi_getopt ("-break-insert", argc, argv,
221  opts, &oind, &oarg);
222  if (opt < 0)
223  break;
224  switch ((enum opt) opt)
225  {
226  case TEMP_OPT:
227  temp_p = 1;
228  break;
229  case HARDWARE_OPT:
230  hardware = 1;
231  break;
232  case CONDITION_OPT:
233  condition = oarg;
234  break;
235  case IGNORE_COUNT_OPT:
236  ignore_count = atol (oarg);
237  break;
238  case THREAD_OPT:
239  thread = atol (oarg);
240  break;
241  case PENDING_OPT:
242  pending = 1;
243  break;
244  case DISABLE_OPT:
245  enabled = 0;
246  break;
247  case TRACEPOINT_OPT:
248  tracepoint = 1;
249  break;
250  case EXPLICIT_SOURCE_OPT:
251  is_explicit = 1;
252  explicit_loc.source_filename = oarg;
253  break;
254  case EXPLICIT_FUNC_OPT:
255  is_explicit = 1;
256  explicit_loc.function_name = oarg;
257  break;
258  case EXPLICIT_LABEL_OPT:
259  is_explicit = 1;
260  explicit_loc.label_name = oarg;
261  break;
262  case EXPLICIT_LINE_OPT:
263  is_explicit = 1;
264  explicit_loc.line_offset = linespec_parse_line_offset (oarg);
265  break;
266  }
267  }
268 
269  if (oind >= argc && !is_explicit)
270  error (_("-%s-insert: Missing <location>"),
271  dprintf ? "dprintf" : "break");
272  if (dprintf)
273  {
274  int format_num = is_explicit ? oind : oind + 1;
275 
276  if (hardware || tracepoint)
277  error (_("-dprintf-insert: does not support -h or -a"));
278  if (format_num >= argc)
279  error (_("-dprintf-insert: Missing <format>"));
280 
281  extra_string = mi_argv_to_format (argv + format_num, argc - format_num);
282  address = argv[oind];
283  }
284  else
285  {
286  if (is_explicit)
287  {
288  if (oind < argc)
289  error (_("-break-insert: Garbage following explicit location"));
290  }
291  else
292  {
293  if (oind < argc - 1)
294  error (_("-break-insert: Garbage following <location>"));
295  address = argv[oind];
296  }
297  }
298 
299  /* Now we have what we need, let's insert the breakpoint! */
300  scoped_restore restore_breakpoint_reporting = setup_breakpoint_reporting ();
301 
302  if (tracepoint)
303  {
304  /* Note that to request a fast tracepoint, the client uses the
305  "hardware" flag, although there's nothing of hardware related to
306  fast tracepoints -- one can implement slow tracepoints with
307  hardware breakpoints, but fast tracepoints are always software.
308  "fast" is a misnomer, actually, "jump" would be more appropriate.
309  A simulator or an emulator could conceivably implement fast
310  regular non-jump based tracepoints. */
311  type_wanted = hardware ? bp_fast_tracepoint : bp_tracepoint;
313  }
314  else if (dprintf)
315  {
316  type_wanted = bp_dprintf;
317  ops = &dprintf_breakpoint_ops;
318  }
319  else
320  {
321  type_wanted = hardware ? bp_hardware_breakpoint : bp_breakpoint;
322  ops = &bkpt_breakpoint_ops;
323  }
324 
325  if (is_explicit)
326  {
327  /* Error check -- we must have one of the other
328  parameters specified. */
329  if (explicit_loc.source_filename != NULL
330  && explicit_loc.function_name == NULL
331  && explicit_loc.label_name == NULL
332  && explicit_loc.line_offset.sign == LINE_OFFSET_UNKNOWN)
333  error (_("-%s-insert: --source option requires --function, --label,"
334  " or --line"), dprintf ? "dprintf" : "break");
335 
336  location = new_explicit_location (&explicit_loc);
337  }
338  else
339  {
340  location = string_to_event_location_basic (&address, current_language,
342  if (*address)
343  error (_("Garbage '%s' at end of location"), address);
344  }
345 
346  create_breakpoint (get_current_arch (), location.get (), condition, thread,
347  extra_string.c_str (),
348  0 /* condition and thread are valid. */,
349  temp_p, type_wanted,
350  ignore_count,
352  ops, 0, enabled, 0, 0);
353 }
354 
355 /* Implements the -break-insert command.
356  See the MI manual for the list of possible options. */
357 
358 void
359 mi_cmd_break_insert (const char *command, char **argv, int argc)
360 {
361  mi_cmd_break_insert_1 (0, command, argv, argc);
362 }
363 
364 /* Implements the -dprintf-insert command.
365  See the MI manual for the list of possible options. */
366 
367 void
368 mi_cmd_dprintf_insert (const char *command, char **argv, int argc)
369 {
370  mi_cmd_break_insert_1 (1, command, argv, argc);
371 }
372 
374 {
378 };
379 
380 void
381 mi_cmd_break_passcount (const char *command, char **argv, int argc)
382 {
383  int n;
384  int p;
385  struct tracepoint *t;
386 
387  if (argc != 2)
388  error (_("Usage: tracepoint-number passcount"));
389 
390  n = atoi (argv[0]);
391  p = atoi (argv[1]);
392  t = get_tracepoint (n);
393 
394  if (t)
395  {
396  t->pass_count = p;
398  }
399  else
400  {
401  error (_("Could not find tracepoint %d"), n);
402  }
403 }
404 
405 /* Insert a watchpoint. The type of watchpoint is specified by the
406  first argument:
407  -break-watch <expr> --> insert a regular wp.
408  -break-watch -r <expr> --> insert a read watchpoint.
409  -break-watch -a <expr> --> insert an access wp. */
410 
411 void
412 mi_cmd_break_watch (const char *command, char **argv, int argc)
413 {
414  char *expr = NULL;
415  enum wp_type type = REG_WP;
416  enum opt
417  {
418  READ_OPT, ACCESS_OPT
419  };
420  static const struct mi_opt opts[] =
421  {
422  {"r", READ_OPT, 0},
423  {"a", ACCESS_OPT, 0},
424  { 0, 0, 0 }
425  };
426 
427  /* Parse arguments. */
428  int oind = 0;
429  char *oarg;
430 
431  while (1)
432  {
433  int opt = mi_getopt ("-break-watch", argc, argv,
434  opts, &oind, &oarg);
435 
436  if (opt < 0)
437  break;
438  switch ((enum opt) opt)
439  {
440  case READ_OPT:
441  type = READ_WP;
442  break;
443  case ACCESS_OPT:
444  type = ACCESS_WP;
445  break;
446  }
447  }
448  if (oind >= argc)
449  error (_("-break-watch: Missing <expression>"));
450  if (oind < argc - 1)
451  error (_("-break-watch: Garbage following <expression>"));
452  expr = argv[oind];
453 
454  /* Now we have what we need, let's insert the watchpoint! */
455  switch (type)
456  {
457  case REG_WP:
458  watch_command_wrapper (expr, FROM_TTY, 0);
459  break;
460  case READ_WP:
461  rwatch_command_wrapper (expr, FROM_TTY, 0);
462  break;
463  case ACCESS_WP:
464  awatch_command_wrapper (expr, FROM_TTY, 0);
465  break;
466  default:
467  error (_("-break-watch: Unknown watchpoint type."));
468  }
469 }
470 
471 /* The mi_read_next_line consults these variable to return successive
472  command lines. While it would be clearer to use a closure pointer,
473  it is not expected that any future code will use read_command_lines_1,
474  therefore no point of overengineering. */
475 
476 static char **mi_command_line_array;
479 
480 static char *
482 {
484  return NULL;
485  else
487 }
488 
489 void
490 mi_cmd_break_commands (const char *command, char **argv, int argc)
491 {
493  char *endptr;
494  int bnum;
495  struct breakpoint *b;
496 
497  if (argc < 1)
498  error (_("USAGE: %s <BKPT> [<COMMAND> [<COMMAND>...]]"), command);
499 
500  bnum = strtol (argv[0], &endptr, 0);
501  if (endptr == argv[0])
502  error (_("breakpoint number argument \"%s\" is not a number."),
503  argv[0]);
504  else if (*endptr != '\0')
505  error (_("junk at the end of breakpoint number argument \"%s\"."),
506  argv[0]);
507 
508  b = get_breakpoint (bnum);
509  if (b == NULL)
510  error (_("breakpoint %d not found."), bnum);
511 
515 
516  if (is_tracepoint (b))
519  else
521 
522  breakpoint_set_commands (b, std::move (break_command));
523 }
524 
const char * string
Definition: signals.c:50
void check_tracepoint_command(char *line, void *closure)
Definition: breakpoint.c:1219
command_line_up read_command_lines_1(char *(*read_next_line_func)(void), int parse_commands, void(*validator)(char *, void *), void *closure)
Definition: cli-script.c:1243
static void breakpoint_notify(struct breakpoint *b)
Definition: mi-cmd-break.c:52
void mi_cmd_break_insert(const char *command, char **argv, int argc)
Definition: mi-cmd-break.c:359
static char * mi_read_next_line(void)
Definition: mi-cmd-break.c:481
bp_type
Definition: mi-cmd-break.c:68
void awatch_command_wrapper(const char *arg, int from_tty, int internal)
Definition: breakpoint.c:11052
struct breakpoint_ops dprintf_breakpoint_ops
Definition: breakpoint.c:261
struct line_offset line_offset
Definition: location.h:102
struct tracepoint * get_tracepoint(int num)
Definition: breakpoint.c:15018
#define _(String)
Definition: gdb_locale.h:35
struct breakpoint_ops tracepoint_breakpoint_ops
Definition: breakpoint.c:13027
#define END_CATCH
event_location_up string_to_event_location_basic(const char **stringp, const struct language_defn *language, symbol_name_match_type match_type)
Definition: location.c:877
void initialize_explicit_location(struct explicit_location *explicit_loc)
Definition: location.c:78
enum offset_relative_sign sign
Definition: location.h:48
scoped_restore_tmpl< T > make_scoped_restore(T *var)
#define TRY
void mi_cmd_break_commands(const char *command, char **argv, int argc)
Definition: mi-cmd-break.c:490
int mi_getopt(const char *prefix, int argc, char **argv, const struct mi_opt *opts, int *oind, char **oarg)
Definition: mi-getopt.c:83
#define CATCH(EXCEPTION, MASK)
static int mi_command_line_array_cnt
Definition: mi-cmd-break.c:477
scoped_restore_tmpl< int > setup_breakpoint_reporting(void)
Definition: mi-cmd-break.c:83
void mi_cmd_break_watch(const char *command, char **argv, int argc)
Definition: mi-cmd-break.c:412
void exception_print(struct ui_file *file, struct gdb_exception e)
Definition: exceptions.c:109
struct observer * observer_attach_breakpoint_created(observer_breakpoint_created_ftype *f)
Definition: gdbtypes.h:749
struct gdbarch * get_current_arch(void)
Definition: arch-utils.c:798
int pass_count
Definition: breakpoint.h:882
struct breakpoint * get_breakpoint(int num)
Definition: breakpoint.c:652
void mi_cmd_break_passcount(const char *command, char **argv, int argc)
Definition: mi-cmd-break.c:381
event_location_up new_explicit_location(const struct explicit_location *explicit_loc)
Definition: location.c:178
std::unique_ptr< event_location, event_location_deleter > event_location_up
Definition: location.h:140
void print_breakpoint(breakpoint *b)
Definition: breakpoint.c:6483
struct breakpoint_ops bkpt_breakpoint_ops
Definition: breakpoint.c:255
void breakpoint_set_commands(struct breakpoint *b, command_line_up &&commands)
Definition: breakpoint.c:1169
bptype
Definition: breakpoint.h:67
void watch_command_wrapper(const char *arg, int from_tty, int internal)
Definition: breakpoint.c:11009
static char ** mi_command_line_array
Definition: mi-cmd-break.c:476
char * function_name
Definition: location.h:91
static int mi_command_line_array_ptr
Definition: mi-cmd-break.c:478
const struct language_defn * current_language
Definition: language.c:81
struct line_offset linespec_parse_line_offset(const char *string)
Definition: linespec.c:1745
#define gdb_stderr
Definition: utils.h:344
event_location_up location
Definition: breakpoint.h:730
int xsnprintf(char *str, size_t size, const char *format,...)
Definition: common-utils.c:134
int create_breakpoint(struct gdbarch *gdbarch, const struct event_location *location, const char *cond_string, int thread, const char *extra_string, int parse_extra, 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:9325
static void mi_cmd_break_insert_1(int dprintf, const char *command, char **argv, int argc)
Definition: mi-cmd-break.c:168
void break_command(const char *arg, int from_tty)
Definition: breakpoint.c:9596
wp_type
Definition: mi-cmd-break.c:373
int ignore_count
Definition: breakpoint.h:711
char * source_filename
Definition: location.h:88
char * label_name
Definition: location.h:97
std::unique_ptr< command_line, command_lines_deleter > command_line_up
Definition: cli-script.h:88
argv
Definition: __init__.py:63
static int mi_can_breakpoint_notify
Definition: mi-cmd-break.c:47
static int mi_breakpoint_observers_installed
Definition: mi-cmd-break.c:43
static std::string mi_argv_to_format(char **argv, int argc)
Definition: mi-cmd-break.c:99
void rwatch_command_wrapper(const char *arg, int from_tty, int internal)
Definition: breakpoint.c:11040
int is_tracepoint(const struct breakpoint *b)
Definition: breakpoint.c:1053
void mi_cmd_dprintf_insert(const char *command, char **argv, int argc)
Definition: mi-cmd-break.c:368
void error(const char *fmt,...)
Definition: errors.c:38
void observer_notify_breakpoint_modified(struct breakpoint *b)