xref: /dragonfly/contrib/gdb-7/gdb/mi/mi-cmd-break.c (revision ef5ccd6c)
15796c8dcSSimon Schubert /* MI Command Set - breakpoint and watchpoint commands.
2*ef5ccd6cSJohn Marino    Copyright (C) 2000-2013 Free Software Foundation, Inc.
35796c8dcSSimon Schubert    Contributed by Cygnus Solutions (a Red Hat company).
45796c8dcSSimon Schubert 
55796c8dcSSimon Schubert    This file is part of GDB.
65796c8dcSSimon Schubert 
75796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
85796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
95796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
105796c8dcSSimon Schubert    (at your option) any later version.
115796c8dcSSimon Schubert 
125796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
135796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
145796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
155796c8dcSSimon Schubert    GNU General Public License for more details.
165796c8dcSSimon Schubert 
175796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
185796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
195796c8dcSSimon Schubert 
205796c8dcSSimon Schubert #include "defs.h"
215796c8dcSSimon Schubert #include "arch-utils.h"
225796c8dcSSimon Schubert #include "mi-cmds.h"
235796c8dcSSimon Schubert #include "ui-out.h"
245796c8dcSSimon Schubert #include "mi-out.h"
255796c8dcSSimon Schubert #include "breakpoint.h"
265796c8dcSSimon Schubert #include "gdb_string.h"
275796c8dcSSimon Schubert #include "mi-getopt.h"
285796c8dcSSimon Schubert #include "gdb.h"
295796c8dcSSimon Schubert #include "exceptions.h"
305796c8dcSSimon Schubert #include "observer.h"
31a45ae5f8SJohn Marino #include "mi-main.h"
32*ef5ccd6cSJohn Marino #include "mi-cmd-break.h"
335796c8dcSSimon Schubert 
345796c8dcSSimon Schubert enum
355796c8dcSSimon Schubert   {
365796c8dcSSimon Schubert     FROM_TTY = 0
375796c8dcSSimon Schubert   };
385796c8dcSSimon Schubert 
395796c8dcSSimon Schubert /* True if MI breakpoint observers have been registered.  */
405796c8dcSSimon Schubert 
415796c8dcSSimon Schubert static int mi_breakpoint_observers_installed;
425796c8dcSSimon Schubert 
435796c8dcSSimon Schubert /* Control whether breakpoint_notify may act.  */
445796c8dcSSimon Schubert 
455796c8dcSSimon Schubert static int mi_can_breakpoint_notify;
465796c8dcSSimon Schubert 
475796c8dcSSimon Schubert /* Output a single breakpoint, when allowed.  */
485796c8dcSSimon Schubert 
495796c8dcSSimon Schubert static void
breakpoint_notify(struct breakpoint * b)50a45ae5f8SJohn Marino breakpoint_notify (struct breakpoint *b)
515796c8dcSSimon Schubert {
525796c8dcSSimon Schubert   if (mi_can_breakpoint_notify)
53a45ae5f8SJohn Marino     gdb_breakpoint_query (current_uiout, b->number, NULL);
545796c8dcSSimon Schubert }
555796c8dcSSimon Schubert 
565796c8dcSSimon Schubert enum bp_type
575796c8dcSSimon Schubert   {
585796c8dcSSimon Schubert     REG_BP,
595796c8dcSSimon Schubert     HW_BP,
605796c8dcSSimon Schubert     REGEXP_BP
615796c8dcSSimon Schubert   };
625796c8dcSSimon Schubert 
63*ef5ccd6cSJohn Marino /* Arrange for all new breakpoints and catchpoints to be reported to
64*ef5ccd6cSJohn Marino    CURRENT_UIOUT until the cleanup returned by this function is run.
65*ef5ccd6cSJohn Marino 
66*ef5ccd6cSJohn Marino    Note that MI output will be probably invalid if more than one
67*ef5ccd6cSJohn Marino    breakpoint is created inside one MI command.  */
68*ef5ccd6cSJohn Marino 
69*ef5ccd6cSJohn Marino struct cleanup *
setup_breakpoint_reporting(void)70*ef5ccd6cSJohn Marino setup_breakpoint_reporting (void)
71*ef5ccd6cSJohn Marino {
72*ef5ccd6cSJohn Marino   struct cleanup *rev_flag;
73*ef5ccd6cSJohn Marino 
74*ef5ccd6cSJohn Marino   if (! mi_breakpoint_observers_installed)
75*ef5ccd6cSJohn Marino     {
76*ef5ccd6cSJohn Marino       observer_attach_breakpoint_created (breakpoint_notify);
77*ef5ccd6cSJohn Marino       mi_breakpoint_observers_installed = 1;
78*ef5ccd6cSJohn Marino     }
79*ef5ccd6cSJohn Marino 
80*ef5ccd6cSJohn Marino   rev_flag = make_cleanup_restore_integer (&mi_can_breakpoint_notify);
81*ef5ccd6cSJohn Marino   mi_can_breakpoint_notify = 1;
82*ef5ccd6cSJohn Marino 
83*ef5ccd6cSJohn Marino   return rev_flag;
84*ef5ccd6cSJohn Marino }
85*ef5ccd6cSJohn Marino 
86*ef5ccd6cSJohn Marino 
875796c8dcSSimon Schubert /* Implements the -break-insert command.
885796c8dcSSimon Schubert    See the MI manual for the list of possible options.  */
895796c8dcSSimon Schubert 
905796c8dcSSimon Schubert void
mi_cmd_break_insert(char * command,char ** argv,int argc)915796c8dcSSimon Schubert mi_cmd_break_insert (char *command, char **argv, int argc)
925796c8dcSSimon Schubert {
935796c8dcSSimon Schubert   char *address = NULL;
94cf7f2e2dSJohn Marino   int hardware = 0;
955796c8dcSSimon Schubert   int temp_p = 0;
965796c8dcSSimon Schubert   int thread = -1;
975796c8dcSSimon Schubert   int ignore_count = 0;
985796c8dcSSimon Schubert   char *condition = NULL;
995796c8dcSSimon Schubert   int pending = 0;
1005796c8dcSSimon Schubert   int enabled = 1;
101cf7f2e2dSJohn Marino   int tracepoint = 0;
102cf7f2e2dSJohn Marino   struct cleanup *back_to;
103cf7f2e2dSJohn Marino   enum bptype type_wanted;
104*ef5ccd6cSJohn Marino   struct breakpoint_ops *ops;
1055796c8dcSSimon Schubert 
1065796c8dcSSimon Schubert   enum opt
1075796c8dcSSimon Schubert     {
108cf7f2e2dSJohn Marino       HARDWARE_OPT, TEMP_OPT, CONDITION_OPT,
109cf7f2e2dSJohn Marino       IGNORE_COUNT_OPT, THREAD_OPT, PENDING_OPT, DISABLE_OPT,
110cf7f2e2dSJohn Marino       TRACEPOINT_OPT,
1115796c8dcSSimon Schubert     };
112a45ae5f8SJohn Marino   static const struct mi_opt opts[] =
1135796c8dcSSimon Schubert   {
1145796c8dcSSimon Schubert     {"h", HARDWARE_OPT, 0},
1155796c8dcSSimon Schubert     {"t", TEMP_OPT, 0},
1165796c8dcSSimon Schubert     {"c", CONDITION_OPT, 1},
1175796c8dcSSimon Schubert     {"i", IGNORE_COUNT_OPT, 1},
1185796c8dcSSimon Schubert     {"p", THREAD_OPT, 1},
1195796c8dcSSimon Schubert     {"f", PENDING_OPT, 0},
1205796c8dcSSimon Schubert     {"d", DISABLE_OPT, 0},
121cf7f2e2dSJohn Marino     {"a", TRACEPOINT_OPT, 0},
1225796c8dcSSimon Schubert     { 0, 0, 0 }
1235796c8dcSSimon Schubert   };
1245796c8dcSSimon Schubert 
1255796c8dcSSimon Schubert   /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
1265796c8dcSSimon Schubert      to denote the end of the option list. */
127*ef5ccd6cSJohn Marino   int oind = 0;
128*ef5ccd6cSJohn Marino   char *oarg;
129cf7f2e2dSJohn Marino 
1305796c8dcSSimon Schubert   while (1)
1315796c8dcSSimon Schubert     {
132c50c785cSJohn Marino       int opt = mi_getopt ("-break-insert", argc, argv,
133*ef5ccd6cSJohn Marino 			   opts, &oind, &oarg);
1345796c8dcSSimon Schubert       if (opt < 0)
1355796c8dcSSimon Schubert 	break;
1365796c8dcSSimon Schubert       switch ((enum opt) opt)
1375796c8dcSSimon Schubert 	{
1385796c8dcSSimon Schubert 	case TEMP_OPT:
1395796c8dcSSimon Schubert 	  temp_p = 1;
1405796c8dcSSimon Schubert 	  break;
1415796c8dcSSimon Schubert 	case HARDWARE_OPT:
142cf7f2e2dSJohn Marino 	  hardware = 1;
1435796c8dcSSimon Schubert 	  break;
1445796c8dcSSimon Schubert 	case CONDITION_OPT:
145*ef5ccd6cSJohn Marino 	  condition = oarg;
1465796c8dcSSimon Schubert 	  break;
1475796c8dcSSimon Schubert 	case IGNORE_COUNT_OPT:
148*ef5ccd6cSJohn Marino 	  ignore_count = atol (oarg);
1495796c8dcSSimon Schubert 	  break;
1505796c8dcSSimon Schubert 	case THREAD_OPT:
151*ef5ccd6cSJohn Marino 	  thread = atol (oarg);
1525796c8dcSSimon Schubert 	  break;
1535796c8dcSSimon Schubert 	case PENDING_OPT:
1545796c8dcSSimon Schubert 	  pending = 1;
1555796c8dcSSimon Schubert 	  break;
1565796c8dcSSimon Schubert 	case DISABLE_OPT:
1575796c8dcSSimon Schubert 	  enabled = 0;
158cf7f2e2dSJohn Marino 	  break;
159cf7f2e2dSJohn Marino 	case TRACEPOINT_OPT:
160cf7f2e2dSJohn Marino 	  tracepoint = 1;
161cf7f2e2dSJohn Marino 	  break;
1625796c8dcSSimon Schubert 	}
1635796c8dcSSimon Schubert     }
1645796c8dcSSimon Schubert 
165*ef5ccd6cSJohn Marino   if (oind >= argc)
166c50c785cSJohn Marino     error (_("-break-insert: Missing <location>"));
167*ef5ccd6cSJohn Marino   if (oind < argc - 1)
168c50c785cSJohn Marino     error (_("-break-insert: Garbage following <location>"));
169*ef5ccd6cSJohn Marino   address = argv[oind];
1705796c8dcSSimon Schubert 
1715796c8dcSSimon Schubert   /* Now we have what we need, let's insert the breakpoint!  */
172*ef5ccd6cSJohn Marino   back_to = setup_breakpoint_reporting ();
173cf7f2e2dSJohn Marino 
174cf7f2e2dSJohn Marino   /* Note that to request a fast tracepoint, the client uses the
175cf7f2e2dSJohn Marino      "hardware" flag, although there's nothing of hardware related to
176cf7f2e2dSJohn Marino      fast tracepoints -- one can implement slow tracepoints with
177cf7f2e2dSJohn Marino      hardware breakpoints, but fast tracepoints are always software.
178cf7f2e2dSJohn Marino      "fast" is a misnomer, actually, "jump" would be more appropriate.
179cf7f2e2dSJohn Marino      A simulator or an emulator could conceivably implement fast
180cf7f2e2dSJohn Marino      regular non-jump based tracepoints.  */
181cf7f2e2dSJohn Marino   type_wanted = (tracepoint
182cf7f2e2dSJohn Marino 		 ? (hardware ? bp_fast_tracepoint : bp_tracepoint)
183cf7f2e2dSJohn Marino 		 : (hardware ? bp_hardware_breakpoint : bp_breakpoint));
184*ef5ccd6cSJohn Marino   ops = tracepoint ? &tracepoint_breakpoint_ops : &bkpt_breakpoint_ops;
185cf7f2e2dSJohn Marino 
186cf7f2e2dSJohn Marino   create_breakpoint (get_current_arch (), address, condition, thread,
187*ef5ccd6cSJohn Marino 		     NULL,
188cf7f2e2dSJohn Marino 		     0 /* condition and thread are valid.  */,
189cf7f2e2dSJohn Marino 		     temp_p, type_wanted,
190cf7f2e2dSJohn Marino 		     ignore_count,
191cf7f2e2dSJohn Marino 		     pending ? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE,
192*ef5ccd6cSJohn Marino 		     ops, 0, enabled, 0, 0);
193cf7f2e2dSJohn Marino   do_cleanups (back_to);
194cf7f2e2dSJohn Marino 
1955796c8dcSSimon Schubert }
1965796c8dcSSimon Schubert 
1975796c8dcSSimon Schubert enum wp_type
1985796c8dcSSimon Schubert {
1995796c8dcSSimon Schubert   REG_WP,
2005796c8dcSSimon Schubert   READ_WP,
2015796c8dcSSimon Schubert   ACCESS_WP
2025796c8dcSSimon Schubert };
2035796c8dcSSimon Schubert 
204cf7f2e2dSJohn Marino void
mi_cmd_break_passcount(char * command,char ** argv,int argc)205cf7f2e2dSJohn Marino mi_cmd_break_passcount (char *command, char **argv, int argc)
206cf7f2e2dSJohn Marino {
207cf7f2e2dSJohn Marino   int n;
208cf7f2e2dSJohn Marino   int p;
209a45ae5f8SJohn Marino   struct tracepoint *t;
210cf7f2e2dSJohn Marino 
211cf7f2e2dSJohn Marino   if (argc != 2)
212cf7f2e2dSJohn Marino     error (_("Usage: tracepoint-number passcount"));
213cf7f2e2dSJohn Marino 
214cf7f2e2dSJohn Marino   n = atoi (argv[0]);
215cf7f2e2dSJohn Marino   p = atoi (argv[1]);
216cf7f2e2dSJohn Marino   t = get_tracepoint (n);
217cf7f2e2dSJohn Marino 
218cf7f2e2dSJohn Marino   if (t)
219cf7f2e2dSJohn Marino     {
220cf7f2e2dSJohn Marino       t->pass_count = p;
221*ef5ccd6cSJohn Marino       observer_notify_breakpoint_modified (&t->base);
222cf7f2e2dSJohn Marino     }
223cf7f2e2dSJohn Marino   else
224cf7f2e2dSJohn Marino     {
225a45ae5f8SJohn Marino       error (_("Could not find tracepoint %d"), n);
226cf7f2e2dSJohn Marino     }
227cf7f2e2dSJohn Marino }
228cf7f2e2dSJohn Marino 
2295796c8dcSSimon Schubert /* Insert a watchpoint. The type of watchpoint is specified by the
2305796c8dcSSimon Schubert    first argument:
2315796c8dcSSimon Schubert    -break-watch <expr> --> insert a regular wp.
2325796c8dcSSimon Schubert    -break-watch -r <expr> --> insert a read watchpoint.
2335796c8dcSSimon Schubert    -break-watch -a <expr> --> insert an access wp.  */
2345796c8dcSSimon Schubert 
2355796c8dcSSimon Schubert void
mi_cmd_break_watch(char * command,char ** argv,int argc)2365796c8dcSSimon Schubert mi_cmd_break_watch (char *command, char **argv, int argc)
2375796c8dcSSimon Schubert {
2385796c8dcSSimon Schubert   char *expr = NULL;
2395796c8dcSSimon Schubert   enum wp_type type = REG_WP;
2405796c8dcSSimon Schubert   enum opt
2415796c8dcSSimon Schubert     {
2425796c8dcSSimon Schubert       READ_OPT, ACCESS_OPT
2435796c8dcSSimon Schubert     };
244a45ae5f8SJohn Marino   static const struct mi_opt opts[] =
2455796c8dcSSimon Schubert   {
2465796c8dcSSimon Schubert     {"r", READ_OPT, 0},
2475796c8dcSSimon Schubert     {"a", ACCESS_OPT, 0},
2485796c8dcSSimon Schubert     { 0, 0, 0 }
2495796c8dcSSimon Schubert   };
2505796c8dcSSimon Schubert 
2515796c8dcSSimon Schubert   /* Parse arguments. */
252*ef5ccd6cSJohn Marino   int oind = 0;
253*ef5ccd6cSJohn Marino   char *oarg;
254cf7f2e2dSJohn Marino 
2555796c8dcSSimon Schubert   while (1)
2565796c8dcSSimon Schubert     {
257c50c785cSJohn Marino       int opt = mi_getopt ("-break-watch", argc, argv,
258*ef5ccd6cSJohn Marino 			   opts, &oind, &oarg);
259cf7f2e2dSJohn Marino 
2605796c8dcSSimon Schubert       if (opt < 0)
2615796c8dcSSimon Schubert 	break;
2625796c8dcSSimon Schubert       switch ((enum opt) opt)
2635796c8dcSSimon Schubert 	{
2645796c8dcSSimon Schubert 	case READ_OPT:
2655796c8dcSSimon Schubert 	  type = READ_WP;
2665796c8dcSSimon Schubert 	  break;
2675796c8dcSSimon Schubert 	case ACCESS_OPT:
2685796c8dcSSimon Schubert 	  type = ACCESS_WP;
2695796c8dcSSimon Schubert 	  break;
2705796c8dcSSimon Schubert 	}
2715796c8dcSSimon Schubert     }
272*ef5ccd6cSJohn Marino   if (oind >= argc)
273c50c785cSJohn Marino     error (_("-break-watch: Missing <expression>"));
274*ef5ccd6cSJohn Marino   if (oind < argc - 1)
275c50c785cSJohn Marino     error (_("-break-watch: Garbage following <expression>"));
276*ef5ccd6cSJohn Marino   expr = argv[oind];
2775796c8dcSSimon Schubert 
2785796c8dcSSimon Schubert   /* Now we have what we need, let's insert the watchpoint!  */
2795796c8dcSSimon Schubert   switch (type)
2805796c8dcSSimon Schubert     {
2815796c8dcSSimon Schubert     case REG_WP:
282c50c785cSJohn Marino       watch_command_wrapper (expr, FROM_TTY, 0);
2835796c8dcSSimon Schubert       break;
2845796c8dcSSimon Schubert     case READ_WP:
285c50c785cSJohn Marino       rwatch_command_wrapper (expr, FROM_TTY, 0);
2865796c8dcSSimon Schubert       break;
2875796c8dcSSimon Schubert     case ACCESS_WP:
288c50c785cSJohn Marino       awatch_command_wrapper (expr, FROM_TTY, 0);
2895796c8dcSSimon Schubert       break;
2905796c8dcSSimon Schubert     default:
291c50c785cSJohn Marino       error (_("-break-watch: Unknown watchpoint type."));
2925796c8dcSSimon Schubert     }
2935796c8dcSSimon Schubert }
2945796c8dcSSimon Schubert 
2955796c8dcSSimon Schubert /* The mi_read_next_line consults these variable to return successive
2965796c8dcSSimon Schubert    command lines.  While it would be clearer to use a closure pointer,
2975796c8dcSSimon Schubert    it is not expected that any future code will use read_command_lines_1,
2985796c8dcSSimon Schubert    therefore no point of overengineering.  */
2995796c8dcSSimon Schubert 
3005796c8dcSSimon Schubert static char **mi_command_line_array;
3015796c8dcSSimon Schubert static int mi_command_line_array_cnt;
3025796c8dcSSimon Schubert static int mi_command_line_array_ptr;
3035796c8dcSSimon Schubert 
3045796c8dcSSimon Schubert static char *
mi_read_next_line(void)305cf7f2e2dSJohn Marino mi_read_next_line (void)
3065796c8dcSSimon Schubert {
3075796c8dcSSimon Schubert   if (mi_command_line_array_ptr == mi_command_line_array_cnt)
3085796c8dcSSimon Schubert     return NULL;
3095796c8dcSSimon Schubert   else
3105796c8dcSSimon Schubert     return mi_command_line_array[mi_command_line_array_ptr++];
3115796c8dcSSimon Schubert }
3125796c8dcSSimon Schubert 
3135796c8dcSSimon Schubert void
mi_cmd_break_commands(char * command,char ** argv,int argc)3145796c8dcSSimon Schubert mi_cmd_break_commands (char *command, char **argv, int argc)
3155796c8dcSSimon Schubert {
3165796c8dcSSimon Schubert   struct command_line *break_command;
3175796c8dcSSimon Schubert   char *endptr;
3185796c8dcSSimon Schubert   int bnum;
3195796c8dcSSimon Schubert   struct breakpoint *b;
3205796c8dcSSimon Schubert 
3215796c8dcSSimon Schubert   if (argc < 1)
322c50c785cSJohn Marino     error (_("USAGE: %s <BKPT> [<COMMAND> [<COMMAND>...]]"), command);
3235796c8dcSSimon Schubert 
3245796c8dcSSimon Schubert   bnum = strtol (argv[0], &endptr, 0);
3255796c8dcSSimon Schubert   if (endptr == argv[0])
326c50c785cSJohn Marino     error (_("breakpoint number argument \"%s\" is not a number."),
3275796c8dcSSimon Schubert 	   argv[0]);
3285796c8dcSSimon Schubert   else if (*endptr != '\0')
329c50c785cSJohn Marino     error (_("junk at the end of breakpoint number argument \"%s\"."),
3305796c8dcSSimon Schubert 	   argv[0]);
3315796c8dcSSimon Schubert 
3325796c8dcSSimon Schubert   b = get_breakpoint (bnum);
3335796c8dcSSimon Schubert   if (b == NULL)
334c50c785cSJohn Marino     error (_("breakpoint %d not found."), bnum);
3355796c8dcSSimon Schubert 
3365796c8dcSSimon Schubert   mi_command_line_array = argv;
3375796c8dcSSimon Schubert   mi_command_line_array_ptr = 1;
3385796c8dcSSimon Schubert   mi_command_line_array_cnt = argc;
3395796c8dcSSimon Schubert 
340cf7f2e2dSJohn Marino   if (is_tracepoint (b))
341cf7f2e2dSJohn Marino     break_command = read_command_lines_1 (mi_read_next_line, 1,
342cf7f2e2dSJohn Marino 					  check_tracepoint_command, b);
343cf7f2e2dSJohn Marino   else
344cf7f2e2dSJohn Marino     break_command = read_command_lines_1 (mi_read_next_line, 1, 0, 0);
345cf7f2e2dSJohn Marino 
3465796c8dcSSimon Schubert   breakpoint_set_commands (b, break_command);
3475796c8dcSSimon Schubert }
3485796c8dcSSimon Schubert 
349