Remove cleanups from prepare_execute_command
[external/binutils.git] / gdb / mi / mi-cmd-break.c
1 /* MI Command Set - breakpoint and watchpoint commands.
2    Copyright (C) 2000-2017 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   {
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     {
56       TRY
57         {
58           print_breakpoint (b);
59         }
60       CATCH (ex, RETURN_MASK_ALL)
61         {
62           exception_print (gdb_stderr, ex);
63         }
64       END_CATCH
65     }
66 }
67
68 enum bp_type
69   {
70     REG_BP,
71     HW_BP,
72     REGEXP_BP
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
82 scoped_restore_tmpl<int>
83 setup_breakpoint_reporting (void)
84 {
85   if (! mi_breakpoint_observers_installed)
86     {
87       observer_attach_breakpoint_created (breakpoint_notify);
88       mi_breakpoint_observers_installed = 1;
89     }
90
91   return make_scoped_restore (&mi_can_breakpoint_notify, 1);
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;
180   event_location_up location;
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;
312       ops = &tracepoint_breakpoint_ops;
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);
341       if (*address)
342         error (_("Garbage '%s' at end of location"), address);
343     }
344
345   create_breakpoint (get_current_arch (), location.get (), condition, thread,
346                      extra_string.c_str (),
347                      0 /* condition and thread are valid.  */,
348                      temp_p, type_wanted,
349                      ignore_count,
350                      pending ? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE,
351                      ops, 0, enabled, 0, 0);
352 }
353
354 /* Implements the -break-insert command.
355    See the MI manual for the list of possible options.  */
356
357 void
358 mi_cmd_break_insert (const char *command, char **argv, int argc)
359 {
360   mi_cmd_break_insert_1 (0, command, argv, argc);
361 }
362
363 /* Implements the -dprintf-insert command.
364    See the MI manual for the list of possible options.  */
365
366 void
367 mi_cmd_dprintf_insert (const char *command, char **argv, int argc)
368 {
369   mi_cmd_break_insert_1 (1, command, argv, argc);
370 }
371
372 enum wp_type
373 {
374   REG_WP,
375   READ_WP,
376   ACCESS_WP
377 };
378
379 void
380 mi_cmd_break_passcount (const char *command, char **argv, int argc)
381 {
382   int n;
383   int p;
384   struct tracepoint *t;
385
386   if (argc != 2)
387     error (_("Usage: tracepoint-number passcount"));
388
389   n = atoi (argv[0]);
390   p = atoi (argv[1]);
391   t = get_tracepoint (n);
392
393   if (t)
394     {
395       t->pass_count = p;
396       observer_notify_breakpoint_modified (t);
397     }
398   else
399     {
400       error (_("Could not find tracepoint %d"), n);
401     }
402 }
403
404 /* Insert a watchpoint. The type of watchpoint is specified by the
405    first argument: 
406    -break-watch <expr> --> insert a regular wp.  
407    -break-watch -r <expr> --> insert a read watchpoint.
408    -break-watch -a <expr> --> insert an access wp.  */
409
410 void
411 mi_cmd_break_watch (const char *command, char **argv, int argc)
412 {
413   char *expr = NULL;
414   enum wp_type type = REG_WP;
415   enum opt
416     {
417       READ_OPT, ACCESS_OPT
418     };
419   static const struct mi_opt opts[] =
420   {
421     {"r", READ_OPT, 0},
422     {"a", ACCESS_OPT, 0},
423     { 0, 0, 0 }
424   };
425
426   /* Parse arguments. */
427   int oind = 0;
428   char *oarg;
429
430   while (1)
431     {
432       int opt = mi_getopt ("-break-watch", argc, argv,
433                            opts, &oind, &oarg);
434
435       if (opt < 0)
436         break;
437       switch ((enum opt) opt)
438         {
439         case READ_OPT:
440           type = READ_WP;
441           break;
442         case ACCESS_OPT:
443           type = ACCESS_WP;
444           break;
445         }
446     }
447   if (oind >= argc)
448     error (_("-break-watch: Missing <expression>"));
449   if (oind < argc - 1)
450     error (_("-break-watch: Garbage following <expression>"));
451   expr = argv[oind];
452
453   /* Now we have what we need, let's insert the watchpoint!  */
454   switch (type)
455     {
456     case REG_WP:
457       watch_command_wrapper (expr, FROM_TTY, 0);
458       break;
459     case READ_WP:
460       rwatch_command_wrapper (expr, FROM_TTY, 0);
461       break;
462     case ACCESS_WP:
463       awatch_command_wrapper (expr, FROM_TTY, 0);
464       break;
465     default:
466       error (_("-break-watch: Unknown watchpoint type."));
467     }
468 }
469
470 /* The mi_read_next_line consults these variable to return successive
471    command lines.  While it would be clearer to use a closure pointer,
472    it is not expected that any future code will use read_command_lines_1,
473    therefore no point of overengineering.  */
474
475 static char **mi_command_line_array;
476 static int mi_command_line_array_cnt;
477 static int mi_command_line_array_ptr;
478
479 static char *
480 mi_read_next_line (void)
481 {
482   if (mi_command_line_array_ptr == mi_command_line_array_cnt)
483     return NULL;
484   else
485     return mi_command_line_array[mi_command_line_array_ptr++];
486 }
487
488 void
489 mi_cmd_break_commands (const char *command, char **argv, int argc)
490 {
491   command_line_up break_command;
492   char *endptr;
493   int bnum;
494   struct breakpoint *b;
495
496   if (argc < 1)
497     error (_("USAGE: %s <BKPT> [<COMMAND> [<COMMAND>...]]"), command);
498
499   bnum = strtol (argv[0], &endptr, 0);
500   if (endptr == argv[0])
501     error (_("breakpoint number argument \"%s\" is not a number."),
502            argv[0]);
503   else if (*endptr != '\0')
504     error (_("junk at the end of breakpoint number argument \"%s\"."),
505            argv[0]);
506
507   b = get_breakpoint (bnum);
508   if (b == NULL)
509     error (_("breakpoint %d not found."), bnum);
510
511   mi_command_line_array = argv;
512   mi_command_line_array_ptr = 1;
513   mi_command_line_array_cnt = argc;
514
515   if (is_tracepoint (b))
516     break_command = read_command_lines_1 (mi_read_next_line, 1,
517                                           check_tracepoint_command, b);
518   else
519     break_command = read_command_lines_1 (mi_read_next_line, 1, 0, 0);
520
521   breakpoint_set_commands (b, std::move (break_command));
522 }
523