1 1.1 christos /* MI Command Set - breakpoint and watchpoint commands. 2 1.11 christos Copyright (C) 2000-2024 Free Software Foundation, Inc. 3 1.1 christos Contributed by Cygnus Solutions (a Red Hat company). 4 1.1 christos 5 1.1 christos This file is part of GDB. 6 1.1 christos 7 1.1 christos This program is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3 of the License, or 10 1.1 christos (at your option) any later version. 11 1.1 christos 12 1.1 christos This program is distributed in the hope that it will be useful, 13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 christos GNU General Public License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 1.1 christos 20 1.1 christos #include "arch-utils.h" 21 1.1 christos #include "mi-cmds.h" 22 1.1 christos #include "ui-out.h" 23 1.1 christos #include "mi-out.h" 24 1.1 christos #include "breakpoint.h" 25 1.1 christos #include "mi-getopt.h" 26 1.8 christos #include "observable.h" 27 1.1 christos #include "mi-main.h" 28 1.1 christos #include "mi-cmd-break.h" 29 1.6 christos #include "language.h" 30 1.6 christos #include "location.h" 31 1.6 christos #include "linespec.h" 32 1.10 christos #include "gdbsupport/gdb_obstack.h" 33 1.1 christos #include <ctype.h> 34 1.8 christos #include "tracepoint.h" 35 1.1 christos 36 1.1 christos enum 37 1.1 christos { 38 1.1 christos FROM_TTY = 0 39 1.1 christos }; 40 1.1 christos 41 1.1 christos /* True if MI breakpoint observers have been registered. */ 42 1.1 christos 43 1.1 christos static int mi_breakpoint_observers_installed; 44 1.1 christos 45 1.1 christos /* Control whether breakpoint_notify may act. */ 46 1.1 christos 47 1.1 christos static int mi_can_breakpoint_notify; 48 1.1 christos 49 1.1 christos /* Output a single breakpoint, when allowed. */ 50 1.1 christos 51 1.1 christos static void 52 1.1 christos breakpoint_notify (struct breakpoint *b) 53 1.1 christos { 54 1.1 christos if (mi_can_breakpoint_notify) 55 1.8 christos { 56 1.9 christos try 57 1.8 christos { 58 1.8 christos print_breakpoint (b); 59 1.8 christos } 60 1.11 christos catch (const gdb_exception_error &ex) 61 1.8 christos { 62 1.8 christos exception_print (gdb_stderr, ex); 63 1.8 christos } 64 1.8 christos } 65 1.1 christos } 66 1.1 christos 67 1.1 christos enum bp_type 68 1.1 christos { 69 1.1 christos REG_BP, 70 1.1 christos HW_BP, 71 1.1 christos REGEXP_BP 72 1.1 christos }; 73 1.1 christos 74 1.1 christos /* Arrange for all new breakpoints and catchpoints to be reported to 75 1.8 christos CURRENT_UIOUT until the destructor of the returned scoped_restore 76 1.8 christos is run. 77 1.1 christos 78 1.1 christos Note that MI output will be probably invalid if more than one 79 1.1 christos breakpoint is created inside one MI command. */ 80 1.1 christos 81 1.8 christos scoped_restore_tmpl<int> 82 1.1 christos setup_breakpoint_reporting (void) 83 1.1 christos { 84 1.1 christos if (! mi_breakpoint_observers_installed) 85 1.1 christos { 86 1.10 christos gdb::observers::breakpoint_created.attach (breakpoint_notify, 87 1.10 christos "mi-cmd-break"); 88 1.1 christos mi_breakpoint_observers_installed = 1; 89 1.1 christos } 90 1.1 christos 91 1.8 christos return make_scoped_restore (&mi_can_breakpoint_notify, 1); 92 1.1 christos } 93 1.1 christos 94 1.1 christos 95 1.11 christos /* Convert arguments in ARGV to a string suitable for parsing by 96 1.11 christos dprintf like "FORMAT",ARG,ARG... and return it. */ 97 1.1 christos 98 1.8 christos static std::string 99 1.11 christos mi_argv_to_format (const char *const *argv, int argc) 100 1.1 christos { 101 1.1 christos int i; 102 1.8 christos std::string result; 103 1.1 christos 104 1.11 christos /* Convert ARGV[0] to format string and save to FORMAT. */ 105 1.8 christos result += '\"'; 106 1.11 christos for (i = 0; argv[0][i] != '\0'; i++) 107 1.1 christos { 108 1.1 christos switch (argv[0][i]) 109 1.1 christos { 110 1.1 christos case '\\': 111 1.8 christos result += "\\\\"; 112 1.1 christos break; 113 1.1 christos case '\a': 114 1.8 christos result += "\\a"; 115 1.1 christos break; 116 1.1 christos case '\b': 117 1.8 christos result += "\\b"; 118 1.1 christos break; 119 1.1 christos case '\f': 120 1.8 christos result += "\\f"; 121 1.1 christos break; 122 1.1 christos case '\n': 123 1.8 christos result += "\\n"; 124 1.1 christos break; 125 1.1 christos case '\r': 126 1.8 christos result += "\\r"; 127 1.1 christos break; 128 1.1 christos case '\t': 129 1.8 christos result += "\\t"; 130 1.1 christos break; 131 1.1 christos case '\v': 132 1.8 christos result += "\\v"; 133 1.1 christos break; 134 1.1 christos case '"': 135 1.8 christos result += "\\\""; 136 1.1 christos break; 137 1.1 christos default: 138 1.1 christos if (isprint (argv[0][i])) 139 1.8 christos result += argv[0][i]; 140 1.1 christos else 141 1.1 christos { 142 1.1 christos char tmp[5]; 143 1.1 christos 144 1.1 christos xsnprintf (tmp, sizeof (tmp), "\\%o", 145 1.1 christos (unsigned char) argv[0][i]); 146 1.8 christos result += tmp; 147 1.1 christos } 148 1.1 christos break; 149 1.1 christos } 150 1.1 christos } 151 1.8 christos result += '\"'; 152 1.1 christos 153 1.11 christos /* Append other arguments. */ 154 1.1 christos for (i = 1; i < argc; i++) 155 1.1 christos { 156 1.8 christos result += ','; 157 1.8 christos result += argv[i]; 158 1.1 christos } 159 1.1 christos 160 1.8 christos return result; 161 1.1 christos } 162 1.1 christos 163 1.1 christos /* Insert breakpoint. 164 1.1 christos If dprintf is true, it will insert dprintf. 165 1.1 christos If not, it will insert other type breakpoint. */ 166 1.1 christos 167 1.1 christos static void 168 1.11 christos mi_cmd_break_insert_1 (int dprintf, const char *command, 169 1.11 christos const char *const *argv, int argc) 170 1.1 christos { 171 1.8 christos const char *address = NULL; 172 1.1 christos int hardware = 0; 173 1.1 christos int temp_p = 0; 174 1.1 christos int thread = -1; 175 1.11 christos int thread_group = -1; 176 1.1 christos int ignore_count = 0; 177 1.11 christos const char *condition = NULL; 178 1.1 christos int pending = 0; 179 1.1 christos int enabled = 1; 180 1.1 christos int tracepoint = 0; 181 1.9 christos symbol_name_match_type match_type = symbol_name_match_type::WILD; 182 1.1 christos enum bptype type_wanted; 183 1.10 christos location_spec_up locspec; 184 1.10 christos const struct breakpoint_ops *ops; 185 1.6 christos int is_explicit = 0; 186 1.10 christos std::unique_ptr<explicit_location_spec> explicit_loc 187 1.10 christos (new explicit_location_spec ()); 188 1.8 christos std::string extra_string; 189 1.10 christos bool force_condition = false; 190 1.1 christos 191 1.1 christos enum opt 192 1.1 christos { 193 1.1 christos HARDWARE_OPT, TEMP_OPT, CONDITION_OPT, 194 1.11 christos IGNORE_COUNT_OPT, THREAD_OPT, THREAD_GROUP_OPT, 195 1.11 christos PENDING_OPT, DISABLE_OPT, 196 1.1 christos TRACEPOINT_OPT, 197 1.10 christos FORCE_CONDITION_OPT, 198 1.9 christos QUALIFIED_OPT, 199 1.6 christos EXPLICIT_SOURCE_OPT, EXPLICIT_FUNC_OPT, 200 1.6 christos EXPLICIT_LABEL_OPT, EXPLICIT_LINE_OPT 201 1.1 christos }; 202 1.1 christos static const struct mi_opt opts[] = 203 1.1 christos { 204 1.1 christos {"h", HARDWARE_OPT, 0}, 205 1.1 christos {"t", TEMP_OPT, 0}, 206 1.1 christos {"c", CONDITION_OPT, 1}, 207 1.1 christos {"i", IGNORE_COUNT_OPT, 1}, 208 1.1 christos {"p", THREAD_OPT, 1}, 209 1.11 christos {"g", THREAD_GROUP_OPT, 1}, 210 1.1 christos {"f", PENDING_OPT, 0}, 211 1.1 christos {"d", DISABLE_OPT, 0}, 212 1.1 christos {"a", TRACEPOINT_OPT, 0}, 213 1.10 christos {"-force-condition", FORCE_CONDITION_OPT, 0}, 214 1.9 christos {"-qualified", QUALIFIED_OPT, 0}, 215 1.6 christos {"-source" , EXPLICIT_SOURCE_OPT, 1}, 216 1.6 christos {"-function", EXPLICIT_FUNC_OPT, 1}, 217 1.6 christos {"-label", EXPLICIT_LABEL_OPT, 1}, 218 1.6 christos {"-line", EXPLICIT_LINE_OPT, 1}, 219 1.1 christos { 0, 0, 0 } 220 1.1 christos }; 221 1.1 christos 222 1.1 christos /* Parse arguments. It could be -r or -h or -t, <location> or ``--'' 223 1.1 christos to denote the end of the option list. */ 224 1.1 christos int oind = 0; 225 1.11 christos const char *oarg; 226 1.1 christos 227 1.1 christos while (1) 228 1.1 christos { 229 1.1 christos int opt = mi_getopt ("-break-insert", argc, argv, 230 1.1 christos opts, &oind, &oarg); 231 1.1 christos if (opt < 0) 232 1.1 christos break; 233 1.1 christos switch ((enum opt) opt) 234 1.1 christos { 235 1.1 christos case TEMP_OPT: 236 1.1 christos temp_p = 1; 237 1.1 christos break; 238 1.1 christos case HARDWARE_OPT: 239 1.1 christos hardware = 1; 240 1.1 christos break; 241 1.1 christos case CONDITION_OPT: 242 1.1 christos condition = oarg; 243 1.1 christos break; 244 1.1 christos case IGNORE_COUNT_OPT: 245 1.1 christos ignore_count = atol (oarg); 246 1.1 christos break; 247 1.1 christos case THREAD_OPT: 248 1.1 christos thread = atol (oarg); 249 1.11 christos if (!valid_global_thread_id (thread)) 250 1.11 christos error (_("Unknown thread %d."), thread); 251 1.11 christos break; 252 1.11 christos case THREAD_GROUP_OPT: 253 1.11 christos thread_group = mi_parse_thread_group_id (oarg); 254 1.1 christos break; 255 1.1 christos case PENDING_OPT: 256 1.1 christos pending = 1; 257 1.1 christos break; 258 1.1 christos case DISABLE_OPT: 259 1.1 christos enabled = 0; 260 1.1 christos break; 261 1.1 christos case TRACEPOINT_OPT: 262 1.1 christos tracepoint = 1; 263 1.1 christos break; 264 1.9 christos case QUALIFIED_OPT: 265 1.9 christos match_type = symbol_name_match_type::FULL; 266 1.9 christos break; 267 1.6 christos case EXPLICIT_SOURCE_OPT: 268 1.6 christos is_explicit = 1; 269 1.11 christos explicit_loc->source_filename = make_unique_xstrdup (oarg); 270 1.6 christos break; 271 1.6 christos case EXPLICIT_FUNC_OPT: 272 1.6 christos is_explicit = 1; 273 1.11 christos explicit_loc->function_name = make_unique_xstrdup (oarg); 274 1.6 christos break; 275 1.6 christos case EXPLICIT_LABEL_OPT: 276 1.6 christos is_explicit = 1; 277 1.11 christos explicit_loc->label_name = make_unique_xstrdup (oarg); 278 1.6 christos break; 279 1.6 christos case EXPLICIT_LINE_OPT: 280 1.6 christos is_explicit = 1; 281 1.10 christos explicit_loc->line_offset = linespec_parse_line_offset (oarg); 282 1.10 christos break; 283 1.10 christos case FORCE_CONDITION_OPT: 284 1.10 christos force_condition = true; 285 1.6 christos break; 286 1.1 christos } 287 1.1 christos } 288 1.1 christos 289 1.6 christos if (oind >= argc && !is_explicit) 290 1.1 christos error (_("-%s-insert: Missing <location>"), 291 1.1 christos dprintf ? "dprintf" : "break"); 292 1.1 christos if (dprintf) 293 1.1 christos { 294 1.6 christos int format_num = is_explicit ? oind : oind + 1; 295 1.1 christos 296 1.1 christos if (hardware || tracepoint) 297 1.1 christos error (_("-dprintf-insert: does not support -h or -a")); 298 1.1 christos if (format_num >= argc) 299 1.1 christos error (_("-dprintf-insert: Missing <format>")); 300 1.1 christos 301 1.1 christos extra_string = mi_argv_to_format (argv + format_num, argc - format_num); 302 1.6 christos address = argv[oind]; 303 1.1 christos } 304 1.1 christos else 305 1.1 christos { 306 1.6 christos if (is_explicit) 307 1.6 christos { 308 1.6 christos if (oind < argc) 309 1.6 christos error (_("-break-insert: Garbage following explicit location")); 310 1.6 christos } 311 1.6 christos else 312 1.6 christos { 313 1.6 christos if (oind < argc - 1) 314 1.6 christos error (_("-break-insert: Garbage following <location>")); 315 1.6 christos address = argv[oind]; 316 1.6 christos } 317 1.1 christos } 318 1.1 christos 319 1.1 christos /* Now we have what we need, let's insert the breakpoint! */ 320 1.8 christos scoped_restore restore_breakpoint_reporting = setup_breakpoint_reporting (); 321 1.1 christos 322 1.1 christos if (tracepoint) 323 1.1 christos { 324 1.1 christos /* Note that to request a fast tracepoint, the client uses the 325 1.1 christos "hardware" flag, although there's nothing of hardware related to 326 1.1 christos fast tracepoints -- one can implement slow tracepoints with 327 1.1 christos hardware breakpoints, but fast tracepoints are always software. 328 1.1 christos "fast" is a misnomer, actually, "jump" would be more appropriate. 329 1.1 christos A simulator or an emulator could conceivably implement fast 330 1.1 christos regular non-jump based tracepoints. */ 331 1.1 christos type_wanted = hardware ? bp_fast_tracepoint : bp_tracepoint; 332 1.10 christos ops = breakpoint_ops_for_location_spec (nullptr, true); 333 1.1 christos } 334 1.1 christos else if (dprintf) 335 1.1 christos { 336 1.1 christos type_wanted = bp_dprintf; 337 1.10 christos ops = &code_breakpoint_ops; 338 1.1 christos } 339 1.1 christos else 340 1.1 christos { 341 1.1 christos type_wanted = hardware ? bp_hardware_breakpoint : bp_breakpoint; 342 1.10 christos ops = &code_breakpoint_ops; 343 1.1 christos } 344 1.1 christos 345 1.6 christos if (is_explicit) 346 1.6 christos { 347 1.6 christos /* Error check -- we must have one of the other 348 1.6 christos parameters specified. */ 349 1.10 christos if (explicit_loc->source_filename != NULL 350 1.10 christos && explicit_loc->function_name == NULL 351 1.10 christos && explicit_loc->label_name == NULL 352 1.10 christos && explicit_loc->line_offset.sign == LINE_OFFSET_UNKNOWN) 353 1.6 christos error (_("-%s-insert: --source option requires --function, --label," 354 1.6 christos " or --line"), dprintf ? "dprintf" : "break"); 355 1.6 christos 356 1.10 christos explicit_loc->func_name_match_type = match_type; 357 1.9 christos 358 1.10 christos locspec = std::move (explicit_loc); 359 1.6 christos } 360 1.6 christos else 361 1.6 christos { 362 1.10 christos locspec = string_to_location_spec_basic (&address, current_language, 363 1.10 christos match_type); 364 1.6 christos if (*address) 365 1.7 christos error (_("Garbage '%s' at end of location"), address); 366 1.6 christos } 367 1.6 christos 368 1.11 christos create_breakpoint (get_current_arch (), locspec.get (), condition, 369 1.11 christos thread, thread_group, 370 1.8 christos extra_string.c_str (), 371 1.10 christos force_condition, 372 1.1 christos 0 /* condition and thread are valid. */, 373 1.1 christos temp_p, type_wanted, 374 1.1 christos ignore_count, 375 1.1 christos pending ? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE, 376 1.1 christos ops, 0, enabled, 0, 0); 377 1.1 christos } 378 1.1 christos 379 1.1 christos /* Implements the -break-insert command. 380 1.1 christos See the MI manual for the list of possible options. */ 381 1.1 christos 382 1.1 christos void 383 1.11 christos mi_cmd_break_insert (const char *command, const char *const *argv, int argc) 384 1.1 christos { 385 1.1 christos mi_cmd_break_insert_1 (0, command, argv, argc); 386 1.1 christos } 387 1.1 christos 388 1.1 christos /* Implements the -dprintf-insert command. 389 1.1 christos See the MI manual for the list of possible options. */ 390 1.1 christos 391 1.1 christos void 392 1.11 christos mi_cmd_dprintf_insert (const char *command, const char *const *argv, int argc) 393 1.1 christos { 394 1.1 christos mi_cmd_break_insert_1 (1, command, argv, argc); 395 1.1 christos } 396 1.1 christos 397 1.10 christos /* Implements the -break-condition command. 398 1.10 christos See the MI manual for the list of options. */ 399 1.10 christos 400 1.10 christos void 401 1.11 christos mi_cmd_break_condition (const char *command, const char *const *argv, 402 1.11 christos int argc) 403 1.10 christos { 404 1.10 christos enum option 405 1.10 christos { 406 1.10 christos FORCE_CONDITION_OPT, 407 1.10 christos }; 408 1.10 christos 409 1.10 christos static const struct mi_opt opts[] = 410 1.10 christos { 411 1.10 christos {"-force", FORCE_CONDITION_OPT, 0}, 412 1.10 christos { 0, 0, 0 } 413 1.10 christos }; 414 1.10 christos 415 1.10 christos /* Parse arguments. */ 416 1.10 christos int oind = 0; 417 1.11 christos const char *oarg; 418 1.10 christos bool force_condition = false; 419 1.10 christos 420 1.10 christos while (true) 421 1.10 christos { 422 1.10 christos int opt = mi_getopt ("-break-condition", argc, argv, 423 1.10 christos opts, &oind, &oarg); 424 1.10 christos if (opt < 0) 425 1.10 christos break; 426 1.10 christos 427 1.10 christos switch (opt) 428 1.10 christos { 429 1.10 christos case FORCE_CONDITION_OPT: 430 1.10 christos force_condition = true; 431 1.10 christos break; 432 1.10 christos } 433 1.10 christos } 434 1.10 christos 435 1.10 christos /* There must be at least one more arg: a bpnum. */ 436 1.10 christos if (oind >= argc) 437 1.10 christos error (_("-break-condition: Missing the <number> argument")); 438 1.10 christos 439 1.10 christos int bpnum = atoi (argv[oind]); 440 1.10 christos 441 1.10 christos /* The rest form the condition expr. */ 442 1.10 christos std::string expr = ""; 443 1.10 christos for (int i = oind + 1; i < argc; ++i) 444 1.10 christos { 445 1.10 christos expr += argv[i]; 446 1.10 christos if (i + 1 < argc) 447 1.10 christos expr += " "; 448 1.10 christos } 449 1.10 christos 450 1.10 christos set_breakpoint_condition (bpnum, expr.c_str (), 0 /* from_tty */, 451 1.10 christos force_condition); 452 1.10 christos } 453 1.10 christos 454 1.1 christos enum wp_type 455 1.1 christos { 456 1.1 christos REG_WP, 457 1.1 christos READ_WP, 458 1.1 christos ACCESS_WP 459 1.1 christos }; 460 1.1 christos 461 1.1 christos void 462 1.11 christos mi_cmd_break_passcount (const char *command, const char *const *argv, 463 1.11 christos int argc) 464 1.1 christos { 465 1.1 christos int n; 466 1.1 christos int p; 467 1.1 christos struct tracepoint *t; 468 1.1 christos 469 1.1 christos if (argc != 2) 470 1.1 christos error (_("Usage: tracepoint-number passcount")); 471 1.1 christos 472 1.1 christos n = atoi (argv[0]); 473 1.1 christos p = atoi (argv[1]); 474 1.1 christos t = get_tracepoint (n); 475 1.1 christos 476 1.1 christos if (t) 477 1.1 christos { 478 1.1 christos t->pass_count = p; 479 1.11 christos notify_breakpoint_modified (t); 480 1.1 christos } 481 1.1 christos else 482 1.1 christos { 483 1.1 christos error (_("Could not find tracepoint %d"), n); 484 1.1 christos } 485 1.1 christos } 486 1.1 christos 487 1.1 christos /* Insert a watchpoint. The type of watchpoint is specified by the 488 1.1 christos first argument: 489 1.1 christos -break-watch <expr> --> insert a regular wp. 490 1.1 christos -break-watch -r <expr> --> insert a read watchpoint. 491 1.1 christos -break-watch -a <expr> --> insert an access wp. */ 492 1.1 christos 493 1.1 christos void 494 1.11 christos mi_cmd_break_watch (const char *command, const char *const *argv, int argc) 495 1.1 christos { 496 1.11 christos const char *expr = NULL; 497 1.1 christos enum wp_type type = REG_WP; 498 1.1 christos enum opt 499 1.1 christos { 500 1.1 christos READ_OPT, ACCESS_OPT 501 1.1 christos }; 502 1.1 christos static const struct mi_opt opts[] = 503 1.1 christos { 504 1.1 christos {"r", READ_OPT, 0}, 505 1.1 christos {"a", ACCESS_OPT, 0}, 506 1.1 christos { 0, 0, 0 } 507 1.1 christos }; 508 1.1 christos 509 1.1 christos /* Parse arguments. */ 510 1.1 christos int oind = 0; 511 1.11 christos const char *oarg; 512 1.1 christos 513 1.1 christos while (1) 514 1.1 christos { 515 1.1 christos int opt = mi_getopt ("-break-watch", argc, argv, 516 1.1 christos opts, &oind, &oarg); 517 1.1 christos 518 1.1 christos if (opt < 0) 519 1.1 christos break; 520 1.1 christos switch ((enum opt) opt) 521 1.1 christos { 522 1.1 christos case READ_OPT: 523 1.1 christos type = READ_WP; 524 1.1 christos break; 525 1.1 christos case ACCESS_OPT: 526 1.1 christos type = ACCESS_WP; 527 1.1 christos break; 528 1.1 christos } 529 1.1 christos } 530 1.1 christos if (oind >= argc) 531 1.1 christos error (_("-break-watch: Missing <expression>")); 532 1.1 christos if (oind < argc - 1) 533 1.1 christos error (_("-break-watch: Garbage following <expression>")); 534 1.1 christos expr = argv[oind]; 535 1.1 christos 536 1.1 christos /* Now we have what we need, let's insert the watchpoint! */ 537 1.1 christos switch (type) 538 1.1 christos { 539 1.1 christos case REG_WP: 540 1.10 christos watch_command_wrapper (expr, FROM_TTY, false); 541 1.1 christos break; 542 1.1 christos case READ_WP: 543 1.10 christos rwatch_command_wrapper (expr, FROM_TTY, false); 544 1.1 christos break; 545 1.1 christos case ACCESS_WP: 546 1.10 christos awatch_command_wrapper (expr, FROM_TTY, false); 547 1.1 christos break; 548 1.1 christos default: 549 1.1 christos error (_("-break-watch: Unknown watchpoint type.")); 550 1.1 christos } 551 1.1 christos } 552 1.1 christos 553 1.1 christos void 554 1.11 christos mi_cmd_break_commands (const char *command, const char *const *argv, int argc) 555 1.1 christos { 556 1.8 christos counted_command_line break_command; 557 1.1 christos char *endptr; 558 1.1 christos int bnum; 559 1.1 christos struct breakpoint *b; 560 1.1 christos 561 1.1 christos if (argc < 1) 562 1.1 christos error (_("USAGE: %s <BKPT> [<COMMAND> [<COMMAND>...]]"), command); 563 1.1 christos 564 1.1 christos bnum = strtol (argv[0], &endptr, 0); 565 1.1 christos if (endptr == argv[0]) 566 1.1 christos error (_("breakpoint number argument \"%s\" is not a number."), 567 1.1 christos argv[0]); 568 1.1 christos else if (*endptr != '\0') 569 1.1 christos error (_("junk at the end of breakpoint number argument \"%s\"."), 570 1.1 christos argv[0]); 571 1.1 christos 572 1.1 christos b = get_breakpoint (bnum); 573 1.1 christos if (b == NULL) 574 1.1 christos error (_("breakpoint %d not found."), bnum); 575 1.1 christos 576 1.8 christos int count = 1; 577 1.8 christos auto reader 578 1.10 christos = [&] (std::string &buffer) 579 1.8 christos { 580 1.8 christos const char *result = nullptr; 581 1.8 christos if (count < argc) 582 1.8 christos result = argv[count++]; 583 1.8 christos return result; 584 1.8 christos }; 585 1.1 christos 586 1.1 christos if (is_tracepoint (b)) 587 1.11 christos { 588 1.11 christos tracepoint *t = gdb::checked_static_cast<tracepoint *> (b); 589 1.11 christos break_command = read_command_lines_1 (reader, 1, 590 1.11 christos [=] (const char *line) 591 1.8 christos { 592 1.11 christos validate_actionline (line, t); 593 1.8 christos }); 594 1.11 christos } 595 1.1 christos else 596 1.8 christos break_command = read_command_lines_1 (reader, 1, 0); 597 1.1 christos 598 1.7 christos breakpoint_set_commands (b, std::move (break_command)); 599 1.1 christos } 600 1.1 christos 601