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 349