netinet{,6}: Assert in{,6}_inithead() are only used for system routing tables.
[dragonfly.git] / contrib / gdb-7 / 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
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 /* Implements the -break-insert command.
88    See the MI manual for the list of possible options.  */
89
90 void
91 mi_cmd_break_insert (char *command, char **argv, int argc)
92 {
93   char *address = NULL;
94   int hardware = 0;
95   int temp_p = 0;
96   int thread = -1;
97   int ignore_count = 0;
98   char *condition = NULL;
99   int pending = 0;
100   int enabled = 1;
101   int tracepoint = 0;
102   struct cleanup *back_to;
103   enum bptype type_wanted;
104   struct breakpoint_ops *ops;
105
106   enum opt
107     {
108       HARDWARE_OPT, TEMP_OPT, CONDITION_OPT,
109       IGNORE_COUNT_OPT, THREAD_OPT, PENDING_OPT, DISABLE_OPT,
110       TRACEPOINT_OPT,
111     };
112   static const struct mi_opt opts[] =
113   {
114     {"h", HARDWARE_OPT, 0},
115     {"t", TEMP_OPT, 0},
116     {"c", CONDITION_OPT, 1},
117     {"i", IGNORE_COUNT_OPT, 1},
118     {"p", THREAD_OPT, 1},
119     {"f", PENDING_OPT, 0},
120     {"d", DISABLE_OPT, 0},
121     {"a", TRACEPOINT_OPT, 0},
122     { 0, 0, 0 }
123   };
124
125   /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
126      to denote the end of the option list. */
127   int oind = 0;
128   char *oarg;
129
130   while (1)
131     {
132       int opt = mi_getopt ("-break-insert", argc, argv,
133                            opts, &oind, &oarg);
134       if (opt < 0)
135         break;
136       switch ((enum opt) opt)
137         {
138         case TEMP_OPT:
139           temp_p = 1;
140           break;
141         case HARDWARE_OPT:
142           hardware = 1;
143           break;
144         case CONDITION_OPT:
145           condition = oarg;
146           break;
147         case IGNORE_COUNT_OPT:
148           ignore_count = atol (oarg);
149           break;
150         case THREAD_OPT:
151           thread = atol (oarg);
152           break;
153         case PENDING_OPT:
154           pending = 1;
155           break;
156         case DISABLE_OPT:
157           enabled = 0;
158           break;
159         case TRACEPOINT_OPT:
160           tracepoint = 1;
161           break;
162         }
163     }
164
165   if (oind >= argc)
166     error (_("-break-insert: Missing <location>"));
167   if (oind < argc - 1)
168     error (_("-break-insert: Garbage following <location>"));
169   address = argv[oind];
170
171   /* Now we have what we need, let's insert the breakpoint!  */
172   back_to = setup_breakpoint_reporting ();
173
174   /* Note that to request a fast tracepoint, the client uses the
175      "hardware" flag, although there's nothing of hardware related to
176      fast tracepoints -- one can implement slow tracepoints with
177      hardware breakpoints, but fast tracepoints are always software.
178      "fast" is a misnomer, actually, "jump" would be more appropriate.
179      A simulator or an emulator could conceivably implement fast
180      regular non-jump based tracepoints.  */
181   type_wanted = (tracepoint
182                  ? (hardware ? bp_fast_tracepoint : bp_tracepoint)
183                  : (hardware ? bp_hardware_breakpoint : bp_breakpoint));
184   ops = tracepoint ? &tracepoint_breakpoint_ops : &bkpt_breakpoint_ops;
185
186   create_breakpoint (get_current_arch (), address, condition, thread,
187                      NULL,
188                      0 /* condition and thread are valid.  */,
189                      temp_p, type_wanted,
190                      ignore_count,
191                      pending ? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE,
192                      ops, 0, enabled, 0, 0);
193   do_cleanups (back_to);
194
195 }
196
197 enum wp_type
198 {
199   REG_WP,
200   READ_WP,
201   ACCESS_WP
202 };
203
204 void
205 mi_cmd_break_passcount (char *command, char **argv, int argc)
206 {
207   int n;
208   int p;
209   struct tracepoint *t;
210
211   if (argc != 2)
212     error (_("Usage: tracepoint-number passcount"));
213
214   n = atoi (argv[0]);
215   p = atoi (argv[1]);
216   t = get_tracepoint (n);
217
218   if (t)
219     {
220       t->pass_count = p;
221       observer_notify_breakpoint_modified (&t->base);
222     }
223   else
224     {
225       error (_("Could not find tracepoint %d"), n);
226     }
227 }
228
229 /* Insert a watchpoint. The type of watchpoint is specified by the
230    first argument: 
231    -break-watch <expr> --> insert a regular wp.  
232    -break-watch -r <expr> --> insert a read watchpoint.
233    -break-watch -a <expr> --> insert an access wp.  */
234
235 void
236 mi_cmd_break_watch (char *command, char **argv, int argc)
237 {
238   char *expr = NULL;
239   enum wp_type type = REG_WP;
240   enum opt
241     {
242       READ_OPT, ACCESS_OPT
243     };
244   static const struct mi_opt opts[] =
245   {
246     {"r", READ_OPT, 0},
247     {"a", ACCESS_OPT, 0},
248     { 0, 0, 0 }
249   };
250
251   /* Parse arguments. */
252   int oind = 0;
253   char *oarg;
254
255   while (1)
256     {
257       int opt = mi_getopt ("-break-watch", argc, argv,
258                            opts, &oind, &oarg);
259
260       if (opt < 0)
261         break;
262       switch ((enum opt) opt)
263         {
264         case READ_OPT:
265           type = READ_WP;
266           break;
267         case ACCESS_OPT:
268           type = ACCESS_WP;
269           break;
270         }
271     }
272   if (oind >= argc)
273     error (_("-break-watch: Missing <expression>"));
274   if (oind < argc - 1)
275     error (_("-break-watch: Garbage following <expression>"));
276   expr = argv[oind];
277
278   /* Now we have what we need, let's insert the watchpoint!  */
279   switch (type)
280     {
281     case REG_WP:
282       watch_command_wrapper (expr, FROM_TTY, 0);
283       break;
284     case READ_WP:
285       rwatch_command_wrapper (expr, FROM_TTY, 0);
286       break;
287     case ACCESS_WP:
288       awatch_command_wrapper (expr, FROM_TTY, 0);
289       break;
290     default:
291       error (_("-break-watch: Unknown watchpoint type."));
292     }
293 }
294
295 /* The mi_read_next_line consults these variable to return successive
296    command lines.  While it would be clearer to use a closure pointer,
297    it is not expected that any future code will use read_command_lines_1,
298    therefore no point of overengineering.  */
299
300 static char **mi_command_line_array;
301 static int mi_command_line_array_cnt;
302 static int mi_command_line_array_ptr;
303
304 static char *
305 mi_read_next_line (void)
306 {
307   if (mi_command_line_array_ptr == mi_command_line_array_cnt)
308     return NULL;
309   else
310     return mi_command_line_array[mi_command_line_array_ptr++];
311 }
312
313 void
314 mi_cmd_break_commands (char *command, char **argv, int argc)
315 {
316   struct command_line *break_command;
317   char *endptr;
318   int bnum;
319   struct breakpoint *b;
320
321   if (argc < 1)
322     error (_("USAGE: %s <BKPT> [<COMMAND> [<COMMAND>...]]"), command);
323
324   bnum = strtol (argv[0], &endptr, 0);
325   if (endptr == argv[0])
326     error (_("breakpoint number argument \"%s\" is not a number."),
327            argv[0]);
328   else if (*endptr != '\0')
329     error (_("junk at the end of breakpoint number argument \"%s\"."),
330            argv[0]);
331
332   b = get_breakpoint (bnum);
333   if (b == NULL)
334     error (_("breakpoint %d not found."), bnum);
335
336   mi_command_line_array = argv;
337   mi_command_line_array_ptr = 1;
338   mi_command_line_array_cnt = argc;
339
340   if (is_tracepoint (b))
341     break_command = read_command_lines_1 (mi_read_next_line, 1,
342                                           check_tracepoint_command, b);
343   else
344     break_command = read_command_lines_1 (mi_read_next_line, 1, 0, 0);
345
346   breakpoint_set_commands (b, break_command);
347 }
348