1b725ae77Skettenis /* MI Command Set - breakpoint and watchpoint commands.
2b725ae77Skettenis Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
3b725ae77Skettenis Contributed by Cygnus Solutions (a Red Hat company).
4b725ae77Skettenis
5b725ae77Skettenis This file is part of GDB.
6b725ae77Skettenis
7b725ae77Skettenis This program is free software; you can redistribute it and/or modify
8b725ae77Skettenis it under the terms of the GNU General Public License as published by
9b725ae77Skettenis the Free Software Foundation; either version 2 of the License, or
10b725ae77Skettenis (at your option) any later version.
11b725ae77Skettenis
12b725ae77Skettenis This program is distributed in the hope that it will be useful,
13b725ae77Skettenis but WITHOUT ANY WARRANTY; without even the implied warranty of
14b725ae77Skettenis MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15b725ae77Skettenis GNU General Public License for more details.
16b725ae77Skettenis
17b725ae77Skettenis You should have received a copy of the GNU General Public License
18b725ae77Skettenis along with this program; if not, write to the Free Software
19b725ae77Skettenis Foundation, Inc., 59 Temple Place - Suite 330,
20b725ae77Skettenis Boston, MA 02111-1307, USA. */
21b725ae77Skettenis
22b725ae77Skettenis #include "defs.h"
23b725ae77Skettenis #include "mi-cmds.h"
24b725ae77Skettenis #include "ui-out.h"
25b725ae77Skettenis #include "mi-out.h"
26b725ae77Skettenis #include "breakpoint.h"
27b725ae77Skettenis #include "gdb_string.h"
28b725ae77Skettenis #include "mi-getopt.h"
29b725ae77Skettenis #include "gdb-events.h"
30b725ae77Skettenis #include "gdb.h"
31b725ae77Skettenis
32b725ae77Skettenis enum
33b725ae77Skettenis {
34b725ae77Skettenis FROM_TTY = 0
35b725ae77Skettenis };
36b725ae77Skettenis
37b725ae77Skettenis /* Output a single breakpoint. */
38b725ae77Skettenis
39b725ae77Skettenis static void
breakpoint_notify(int b)40b725ae77Skettenis breakpoint_notify (int b)
41b725ae77Skettenis {
42b725ae77Skettenis gdb_breakpoint_query (uiout, b);
43b725ae77Skettenis }
44b725ae77Skettenis
45b725ae77Skettenis
46b725ae77Skettenis struct gdb_events breakpoint_hooks =
47b725ae77Skettenis {
48b725ae77Skettenis breakpoint_notify,
49b725ae77Skettenis breakpoint_notify,
50b725ae77Skettenis breakpoint_notify,
51b725ae77Skettenis };
52b725ae77Skettenis
53b725ae77Skettenis
54b725ae77Skettenis enum bp_type
55b725ae77Skettenis {
56b725ae77Skettenis REG_BP,
57b725ae77Skettenis HW_BP,
58b725ae77Skettenis REGEXP_BP
59b725ae77Skettenis };
60b725ae77Skettenis
61b725ae77Skettenis /* Insert a breakpoint. The type of breakpoint is specified by the
62b725ae77Skettenis first argument: -break-insert <location> --> insert a regular
63b725ae77Skettenis breakpoint. -break-insert -t <location> --> insert a temporary
64b725ae77Skettenis breakpoint. -break-insert -h <location> --> insert an hardware
65b725ae77Skettenis breakpoint. -break-insert -t -h <location> --> insert a temporary
66b725ae77Skettenis hw bp.
67b725ae77Skettenis -break-insert -r <regexp> --> insert a bp at functions matching
68b725ae77Skettenis <regexp> */
69b725ae77Skettenis
70b725ae77Skettenis enum mi_cmd_result
mi_cmd_break_insert(char * command,char ** argv,int argc)71b725ae77Skettenis mi_cmd_break_insert (char *command, char **argv, int argc)
72b725ae77Skettenis {
73b725ae77Skettenis char *address = NULL;
74b725ae77Skettenis enum bp_type type = REG_BP;
75b725ae77Skettenis int temp_p = 0;
76b725ae77Skettenis int thread = -1;
77b725ae77Skettenis int ignore_count = 0;
78b725ae77Skettenis char *condition = NULL;
79b725ae77Skettenis enum gdb_rc rc;
80b725ae77Skettenis struct gdb_events *old_hooks;
81b725ae77Skettenis enum opt
82b725ae77Skettenis {
83b725ae77Skettenis HARDWARE_OPT, TEMP_OPT /*, REGEXP_OPT */ , CONDITION_OPT,
84b725ae77Skettenis IGNORE_COUNT_OPT, THREAD_OPT
85b725ae77Skettenis };
86b725ae77Skettenis static struct mi_opt opts[] =
87b725ae77Skettenis {
88b725ae77Skettenis {"h", HARDWARE_OPT, 0},
89b725ae77Skettenis {"t", TEMP_OPT, 0},
90b725ae77Skettenis {"c", CONDITION_OPT, 1},
91b725ae77Skettenis {"i", IGNORE_COUNT_OPT, 1},
92b725ae77Skettenis {"p", THREAD_OPT, 1},
93b725ae77Skettenis 0
94b725ae77Skettenis };
95b725ae77Skettenis
96b725ae77Skettenis /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
97b725ae77Skettenis to denote the end of the option list. */
98b725ae77Skettenis int optind = 0;
99b725ae77Skettenis char *optarg;
100b725ae77Skettenis while (1)
101b725ae77Skettenis {
102b725ae77Skettenis int opt = mi_getopt ("mi_cmd_break_insert", argc, argv, opts, &optind, &optarg);
103b725ae77Skettenis if (opt < 0)
104b725ae77Skettenis break;
105b725ae77Skettenis switch ((enum opt) opt)
106b725ae77Skettenis {
107b725ae77Skettenis case TEMP_OPT:
108b725ae77Skettenis temp_p = 1;
109b725ae77Skettenis break;
110b725ae77Skettenis case HARDWARE_OPT:
111b725ae77Skettenis type = HW_BP;
112b725ae77Skettenis break;
113b725ae77Skettenis #if 0
114b725ae77Skettenis case REGEXP_OPT:
115b725ae77Skettenis type = REGEXP_BP;
116b725ae77Skettenis break;
117b725ae77Skettenis #endif
118b725ae77Skettenis case CONDITION_OPT:
119b725ae77Skettenis condition = optarg;
120b725ae77Skettenis break;
121b725ae77Skettenis case IGNORE_COUNT_OPT:
122b725ae77Skettenis ignore_count = atol (optarg);
123b725ae77Skettenis break;
124b725ae77Skettenis case THREAD_OPT:
125b725ae77Skettenis thread = atol (optarg);
126b725ae77Skettenis break;
127b725ae77Skettenis }
128b725ae77Skettenis }
129b725ae77Skettenis
130b725ae77Skettenis if (optind >= argc)
131b725ae77Skettenis error ("mi_cmd_break_insert: Missing <location>");
132b725ae77Skettenis if (optind < argc - 1)
133b725ae77Skettenis error ("mi_cmd_break_insert: Garbage following <location>");
134b725ae77Skettenis address = argv[optind];
135b725ae77Skettenis
136b725ae77Skettenis /* Now we have what we need, let's insert the breakpoint! */
137*11efff7fSkettenis old_hooks = deprecated_set_gdb_event_hooks (&breakpoint_hooks);
138b725ae77Skettenis switch (type)
139b725ae77Skettenis {
140b725ae77Skettenis case REG_BP:
141b725ae77Skettenis rc = gdb_breakpoint (address, condition,
142b725ae77Skettenis 0 /*hardwareflag */ , temp_p,
143b725ae77Skettenis thread, ignore_count);
144b725ae77Skettenis break;
145b725ae77Skettenis case HW_BP:
146b725ae77Skettenis rc = gdb_breakpoint (address, condition,
147b725ae77Skettenis 1 /*hardwareflag */ , temp_p,
148b725ae77Skettenis thread, ignore_count);
149b725ae77Skettenis break;
150b725ae77Skettenis #if 0
151b725ae77Skettenis case REGEXP_BP:
152b725ae77Skettenis if (temp_p)
153b725ae77Skettenis error ("mi_cmd_break_insert: Unsupported tempoary regexp breakpoint");
154b725ae77Skettenis else
155b725ae77Skettenis rbreak_command_wrapper (address, FROM_TTY);
156b725ae77Skettenis return MI_CMD_DONE;
157b725ae77Skettenis break;
158b725ae77Skettenis #endif
159b725ae77Skettenis default:
160b725ae77Skettenis internal_error (__FILE__, __LINE__,
161b725ae77Skettenis "mi_cmd_break_insert: Bad switch.");
162b725ae77Skettenis }
163*11efff7fSkettenis deprecated_set_gdb_event_hooks (old_hooks);
164b725ae77Skettenis
165b725ae77Skettenis if (rc == GDB_RC_FAIL)
166b725ae77Skettenis return MI_CMD_CAUGHT_ERROR;
167b725ae77Skettenis else
168b725ae77Skettenis return MI_CMD_DONE;
169b725ae77Skettenis }
170b725ae77Skettenis
171b725ae77Skettenis enum wp_type
172b725ae77Skettenis {
173b725ae77Skettenis REG_WP,
174b725ae77Skettenis READ_WP,
175b725ae77Skettenis ACCESS_WP
176b725ae77Skettenis };
177b725ae77Skettenis
178b725ae77Skettenis /* Insert a watchpoint. The type of watchpoint is specified by the
179b725ae77Skettenis first argument:
180b725ae77Skettenis -break-watch <expr> --> insert a regular wp.
181b725ae77Skettenis -break-watch -r <expr> --> insert a read watchpoint.
182b725ae77Skettenis -break-watch -a <expr> --> insert an access wp. */
183b725ae77Skettenis
184b725ae77Skettenis enum mi_cmd_result
mi_cmd_break_watch(char * command,char ** argv,int argc)185b725ae77Skettenis mi_cmd_break_watch (char *command, char **argv, int argc)
186b725ae77Skettenis {
187b725ae77Skettenis char *expr = NULL;
188b725ae77Skettenis enum wp_type type = REG_WP;
189b725ae77Skettenis enum opt
190b725ae77Skettenis {
191b725ae77Skettenis READ_OPT, ACCESS_OPT
192b725ae77Skettenis };
193b725ae77Skettenis static struct mi_opt opts[] =
194b725ae77Skettenis {
195b725ae77Skettenis {"r", READ_OPT, 0},
196b725ae77Skettenis {"a", ACCESS_OPT, 0},
197b725ae77Skettenis 0
198b725ae77Skettenis };
199b725ae77Skettenis
200b725ae77Skettenis /* Parse arguments. */
201b725ae77Skettenis int optind = 0;
202b725ae77Skettenis char *optarg;
203b725ae77Skettenis while (1)
204b725ae77Skettenis {
205b725ae77Skettenis int opt = mi_getopt ("mi_cmd_break_watch", argc, argv, opts, &optind, &optarg);
206b725ae77Skettenis if (opt < 0)
207b725ae77Skettenis break;
208b725ae77Skettenis switch ((enum opt) opt)
209b725ae77Skettenis {
210b725ae77Skettenis case READ_OPT:
211b725ae77Skettenis type = READ_WP;
212b725ae77Skettenis break;
213b725ae77Skettenis case ACCESS_OPT:
214b725ae77Skettenis type = ACCESS_WP;
215b725ae77Skettenis break;
216b725ae77Skettenis }
217b725ae77Skettenis }
218b725ae77Skettenis if (optind >= argc)
219b725ae77Skettenis error ("mi_cmd_break_watch: Missing <expression>");
220b725ae77Skettenis if (optind < argc - 1)
221b725ae77Skettenis error ("mi_cmd_break_watch: Garbage following <expression>");
222b725ae77Skettenis expr = argv[optind];
223b725ae77Skettenis
224b725ae77Skettenis /* Now we have what we need, let's insert the watchpoint! */
225b725ae77Skettenis switch (type)
226b725ae77Skettenis {
227b725ae77Skettenis case REG_WP:
228b725ae77Skettenis watch_command_wrapper (expr, FROM_TTY);
229b725ae77Skettenis break;
230b725ae77Skettenis case READ_WP:
231b725ae77Skettenis rwatch_command_wrapper (expr, FROM_TTY);
232b725ae77Skettenis break;
233b725ae77Skettenis case ACCESS_WP:
234b725ae77Skettenis awatch_command_wrapper (expr, FROM_TTY);
235b725ae77Skettenis break;
236b725ae77Skettenis default:
237b725ae77Skettenis error ("mi_cmd_break_watch: Unknown watchpoint type.");
238b725ae77Skettenis }
239b725ae77Skettenis return MI_CMD_DONE;
240b725ae77Skettenis }
241