Implement '-target-detach pid'.
[deliverable/binutils-gdb.git] / gdb / mi / mi-cmd-break.c
1 /* MI Command Set - breakpoint and watchpoint commands.
2 Copyright (C) 2000, 2001, 2002, 2007, 2008 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 "mi-cmds.h"
22 #include "ui-out.h"
23 #include "mi-out.h"
24 #include "breakpoint.h"
25 #include "gdb_string.h"
26 #include "mi-getopt.h"
27 #include "gdb.h"
28 #include "exceptions.h"
29 #include "observer.h"
30
31 enum
32 {
33 FROM_TTY = 0
34 };
35
36 /* True if MI breakpoint observers have been registered. */
37
38 static int mi_breakpoint_observers_installed;
39
40 /* Control whether breakpoint_notify may act. */
41
42 static int mi_can_breakpoint_notify;
43
44 /* Output a single breakpoint, when allowed. */
45
46 static void
47 breakpoint_notify (int b)
48 {
49 if (mi_can_breakpoint_notify)
50 gdb_breakpoint_query (uiout, b, NULL);
51 }
52
53 enum bp_type
54 {
55 REG_BP,
56 HW_BP,
57 REGEXP_BP
58 };
59
60 /* Implements the -break-insert command.
61 See the MI manual for the list of possible options. */
62
63 void
64 mi_cmd_break_insert (char *command, char **argv, int argc)
65 {
66 char *address = NULL;
67 enum bp_type type = REG_BP;
68 int temp_p = 0;
69 int thread = -1;
70 int ignore_count = 0;
71 char *condition = NULL;
72 int pending = 0;
73 struct gdb_exception e;
74 struct gdb_events *old_hooks;
75 enum opt
76 {
77 HARDWARE_OPT, TEMP_OPT /*, REGEXP_OPT */ , CONDITION_OPT,
78 IGNORE_COUNT_OPT, THREAD_OPT, PENDING_OPT
79 };
80 static struct mi_opt opts[] =
81 {
82 {"h", HARDWARE_OPT, 0},
83 {"t", TEMP_OPT, 0},
84 {"c", CONDITION_OPT, 1},
85 {"i", IGNORE_COUNT_OPT, 1},
86 {"p", THREAD_OPT, 1},
87 {"f", PENDING_OPT, 0},
88 { 0, 0, 0 }
89 };
90
91 /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
92 to denote the end of the option list. */
93 int optind = 0;
94 char *optarg;
95 while (1)
96 {
97 int opt = mi_getopt ("mi_cmd_break_insert", argc, argv, opts, &optind, &optarg);
98 if (opt < 0)
99 break;
100 switch ((enum opt) opt)
101 {
102 case TEMP_OPT:
103 temp_p = 1;
104 break;
105 case HARDWARE_OPT:
106 type = HW_BP;
107 break;
108 #if 0
109 case REGEXP_OPT:
110 type = REGEXP_BP;
111 break;
112 #endif
113 case CONDITION_OPT:
114 condition = optarg;
115 break;
116 case IGNORE_COUNT_OPT:
117 ignore_count = atol (optarg);
118 break;
119 case THREAD_OPT:
120 thread = atol (optarg);
121 break;
122 case PENDING_OPT:
123 pending = 1;
124 break;
125 }
126 }
127
128 if (optind >= argc)
129 error (_("mi_cmd_break_insert: Missing <location>"));
130 if (optind < argc - 1)
131 error (_("mi_cmd_break_insert: Garbage following <location>"));
132 address = argv[optind];
133
134 /* Now we have what we need, let's insert the breakpoint! */
135 if (! mi_breakpoint_observers_installed)
136 {
137 observer_attach_breakpoint_created (breakpoint_notify);
138 observer_attach_breakpoint_modified (breakpoint_notify);
139 observer_attach_breakpoint_deleted (breakpoint_notify);
140 mi_breakpoint_observers_installed = 1;
141 }
142
143 mi_can_breakpoint_notify = 1;
144 /* Make sure we restore hooks even if exception is thrown. */
145 TRY_CATCH (e, RETURN_MASK_ALL)
146 {
147 switch (type)
148 {
149 case REG_BP:
150 set_breakpoint (address, condition,
151 0 /*hardwareflag */ , temp_p,
152 thread, ignore_count,
153 pending);
154 break;
155 case HW_BP:
156 set_breakpoint (address, condition,
157 1 /*hardwareflag */ , temp_p,
158 thread, ignore_count,
159 pending);
160 break;
161 #if 0
162 case REGEXP_BP:
163 if (temp_p)
164 error (_("mi_cmd_break_insert: Unsupported tempoary regexp breakpoint"));
165 else
166 rbreak_command_wrapper (address, FROM_TTY);
167 break;
168 #endif
169 default:
170 internal_error (__FILE__, __LINE__,
171 _("mi_cmd_break_insert: Bad switch."));
172 }
173 }
174 mi_can_breakpoint_notify = 0;
175 if (e.reason < 0)
176 throw_exception (e);
177 }
178
179 enum wp_type
180 {
181 REG_WP,
182 READ_WP,
183 ACCESS_WP
184 };
185
186 /* Insert a watchpoint. The type of watchpoint is specified by the
187 first argument:
188 -break-watch <expr> --> insert a regular wp.
189 -break-watch -r <expr> --> insert a read watchpoint.
190 -break-watch -a <expr> --> insert an access wp. */
191
192 void
193 mi_cmd_break_watch (char *command, char **argv, int argc)
194 {
195 char *expr = NULL;
196 enum wp_type type = REG_WP;
197 enum opt
198 {
199 READ_OPT, ACCESS_OPT
200 };
201 static struct mi_opt opts[] =
202 {
203 {"r", READ_OPT, 0},
204 {"a", ACCESS_OPT, 0},
205 { 0, 0, 0 }
206 };
207
208 /* Parse arguments. */
209 int optind = 0;
210 char *optarg;
211 while (1)
212 {
213 int opt = mi_getopt ("mi_cmd_break_watch", argc, argv, opts, &optind, &optarg);
214 if (opt < 0)
215 break;
216 switch ((enum opt) opt)
217 {
218 case READ_OPT:
219 type = READ_WP;
220 break;
221 case ACCESS_OPT:
222 type = ACCESS_WP;
223 break;
224 }
225 }
226 if (optind >= argc)
227 error (_("mi_cmd_break_watch: Missing <expression>"));
228 if (optind < argc - 1)
229 error (_("mi_cmd_break_watch: Garbage following <expression>"));
230 expr = argv[optind];
231
232 /* Now we have what we need, let's insert the watchpoint! */
233 switch (type)
234 {
235 case REG_WP:
236 watch_command_wrapper (expr, FROM_TTY);
237 break;
238 case READ_WP:
239 rwatch_command_wrapper (expr, FROM_TTY);
240 break;
241 case ACCESS_WP:
242 awatch_command_wrapper (expr, FROM_TTY);
243 break;
244 default:
245 error (_("mi_cmd_break_watch: Unknown watchpoint type."));
246 }
247 }
This page took 0.036482 seconds and 4 git commands to generate.