mi-cmd-break.c revision 1.11 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