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