]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame_incremental - gdb/mi/mi-cmd-stack.c
gdb: add Aaron Griffith to gdb/MAINTAINERS
[thirdparty/binutils-gdb.git] / gdb / mi / mi-cmd-stack.c
... / ...
CommitLineData
1/* MI Command Set - stack commands.
2 Copyright (C) 2000-2025 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 "event-top.h"
21#include "frame.h"
22#include "value.h"
23#include "mi-cmds.h"
24#include "ui-out.h"
25#include "symtab.h"
26#include "block.h"
27#include "dictionary.h"
28#include "language.h"
29#include "valprint.h"
30#include "mi-getopt.h"
31#include "extension.h"
32#include <ctype.h>
33#include "mi-parse.h"
34#include <optional>
35#include "gdbsupport/gdb-safe-ctype.h"
36#include "inferior.h"
37
38enum what_to_list { locals, arguments, all };
39
40static void list_args_or_locals (const frame_print_options &fp_opts,
41 enum what_to_list what,
42 enum print_values values,
43 const frame_info_ptr &fi,
44 int skip_unavailable);
45
46/* True if we want to allow Python-based frame filters. */
47static int frame_filters = 0;
48
49void
50mi_cmd_enable_frame_filters (const char *command, const char *const *argv,
51 int argc)
52{
53 if (argc != 0)
54 error (_("-enable-frame-filters: no arguments allowed"));
55 frame_filters = 1;
56}
57
58/* Like apply_ext_lang_frame_filter, but take a print_values */
59
60static enum ext_lang_bt_status
61mi_apply_ext_lang_frame_filter (const frame_info_ptr &frame,
62 frame_filter_flags flags,
63 enum print_values print_values,
64 struct ui_out *out,
65 int frame_low, int frame_high)
66{
67 /* ext_lang_frame_args's MI options are compatible with MI print
68 values. */
69 return apply_ext_lang_frame_filter (frame, flags,
70 (enum ext_lang_frame_args) print_values,
71 out,
72 frame_low, frame_high);
73}
74
75/* Print a list of the stack frames. Args can be none, in which case
76 we want to print the whole backtrace, or a pair of numbers
77 specifying the frame numbers at which to start and stop the
78 display. If the two numbers are equal, a single frame will be
79 displayed. */
80
81void
82mi_cmd_stack_list_frames (const char *command, const char *const *argv,
83 int argc)
84{
85 int frame_low;
86 int frame_high;
87 int i;
88 frame_info_ptr fi;
89 enum ext_lang_bt_status result = EXT_LANG_BT_ERROR;
90 int raw_arg = 0;
91 int oind = 0;
92 enum opt
93 {
94 NO_FRAME_FILTERS
95 };
96 static const struct mi_opt opts[] =
97 {
98 {"-no-frame-filters", NO_FRAME_FILTERS, 0},
99 { 0, 0, 0 }
100 };
101
102 /* Parse arguments. In this instance we are just looking for
103 --no-frame-filters. */
104 while (1)
105 {
106 const char *oarg;
107 int opt = mi_getopt ("-stack-list-frames", argc, argv,
108 opts, &oind, &oarg);
109 if (opt < 0)
110 break;
111 switch ((enum opt) opt)
112 {
113 case NO_FRAME_FILTERS:
114 raw_arg = oind;
115 break;
116 }
117 }
118
119 /* After the last option is parsed, there should either be low -
120 high range, or no further arguments. */
121 if ((argc - oind != 0) && (argc - oind != 2))
122 error (_("-stack-list-frames: Usage: [--no-frame-filters] [FRAME_LOW FRAME_HIGH]"));
123
124 /* If there is a range, set it. */
125 if (argc - oind == 2)
126 {
127 frame_low = atoi (argv[0 + oind]);
128 frame_high = atoi (argv[1 + oind]);
129 }
130 else
131 {
132 /* Called with no arguments, it means we want the whole
133 backtrace. */
134 frame_low = -1;
135 frame_high = -1;
136 }
137
138 /* Let's position fi on the frame at which to start the
139 display. Could be the innermost frame if the whole stack needs
140 displaying, or if frame_low is 0. */
141 for (i = 0, fi = get_current_frame ();
142 fi && i < frame_low;
143 i++, fi = get_prev_frame (fi));
144
145 if (fi == NULL)
146 error (_("-stack-list-frames: Not enough frames in stack."));
147
148 ui_out_emit_list list_emitter (current_uiout, "stack");
149
150 if (! raw_arg && frame_filters)
151 {
152 frame_filter_flags flags = PRINT_LEVEL | PRINT_FRAME_INFO;
153 int py_frame_low = frame_low;
154
155 /* We cannot pass -1 to frame_low, as that would signify a
156 relative backtrace from the tail of the stack. So, in the case
157 of frame_low == -1, assign and increment it. */
158 if (py_frame_low == -1)
159 py_frame_low++;
160
161 result = apply_ext_lang_frame_filter (get_current_frame (), flags,
162 NO_VALUES, current_uiout,
163 py_frame_low, frame_high);
164 }
165
166 /* Run the inbuilt backtrace if there are no filters registered, or
167 if "--no-frame-filters" has been specified from the command. */
168 if (! frame_filters || raw_arg || result == EXT_LANG_BT_NO_FILTERS)
169 {
170 /* Now let's print the frames up to frame_high, or until there are
171 frames in the stack. */
172 for (;
173 fi && (i <= frame_high || frame_high == -1);
174 i++, fi = get_prev_frame (fi))
175 {
176 QUIT;
177 /* Print the location and the address always, even for level 0.
178 If args is 0, don't print the arguments. */
179 print_frame_info (user_frame_print_options,
180 fi, 1, LOC_AND_ADDRESS, 0 /* args */, 0);
181 }
182 }
183}
184
185void
186mi_cmd_stack_info_depth (const char *command, const char *const *argv,
187 int argc)
188{
189 int frame_high;
190 int i;
191 frame_info_ptr fi;
192
193 if (argc > 1)
194 error (_("-stack-info-depth: Usage: [MAX_DEPTH]"));
195
196 if (argc == 1)
197 frame_high = atoi (argv[0]);
198 else
199 /* Called with no arguments, it means we want the real depth of
200 the stack. */
201 frame_high = -1;
202
203 for (i = 0, fi = get_current_frame ();
204 fi && (i < frame_high || frame_high == -1);
205 i++, fi = get_prev_frame (fi))
206 QUIT;
207
208 current_uiout->field_signed ("depth", i);
209}
210
211/* Print a list of the locals for the current frame. With argument of
212 0, print only the names, with argument of 1 print also the
213 values. */
214
215void
216mi_cmd_stack_list_locals (const char *command, const char *const *argv,
217 int argc)
218{
219 frame_info_ptr frame;
220 int raw_arg = 0;
221 enum ext_lang_bt_status result = EXT_LANG_BT_ERROR;
222 enum print_values print_value;
223 int oind = 0;
224 int skip_unavailable = 0;
225
226 if (argc > 1)
227 {
228 enum opt
229 {
230 NO_FRAME_FILTERS,
231 SKIP_UNAVAILABLE,
232 };
233 static const struct mi_opt opts[] =
234 {
235 {"-no-frame-filters", NO_FRAME_FILTERS, 0},
236 {"-skip-unavailable", SKIP_UNAVAILABLE, 0},
237 { 0, 0, 0 }
238 };
239
240 while (1)
241 {
242 const char *oarg;
243 /* Don't parse 'print-values' as an option. */
244 int opt = mi_getopt ("-stack-list-locals", argc - 1, argv,
245 opts, &oind, &oarg);
246
247 if (opt < 0)
248 break;
249 switch ((enum opt) opt)
250 {
251 case NO_FRAME_FILTERS:
252 raw_arg = oind;
253 break;
254 case SKIP_UNAVAILABLE:
255 skip_unavailable = 1;
256 break;
257 }
258 }
259 }
260
261 /* After the last option is parsed, there should be only
262 'print-values'. */
263 if (argc - oind != 1)
264 error (_("-stack-list-locals: Usage: [--no-frame-filters] "
265 "[--skip-unavailable] PRINT_VALUES"));
266
267 frame = get_selected_frame (NULL);
268 print_value = mi_parse_print_values (argv[oind]);
269
270 if (! raw_arg && frame_filters)
271 {
272 frame_filter_flags flags = PRINT_LEVEL | PRINT_LOCALS;
273
274 result = mi_apply_ext_lang_frame_filter (frame, flags, print_value,
275 current_uiout, 0, 0);
276 }
277
278 /* Run the inbuilt backtrace if there are no filters registered, or
279 if "--no-frame-filters" has been specified from the command. */
280 if (! frame_filters || raw_arg || result == EXT_LANG_BT_NO_FILTERS)
281 {
282 list_args_or_locals (user_frame_print_options,
283 locals, print_value, frame,
284 skip_unavailable);
285 }
286}
287
288/* Print a list of the arguments for the current frame. With argument
289 of 0, print only the names, with argument of 1 print also the
290 values. */
291
292void
293mi_cmd_stack_list_args (const char *command, const char *const *argv, int argc)
294{
295 int frame_low;
296 int frame_high;
297 int i;
298 frame_info_ptr fi;
299 enum print_values print_values;
300 struct ui_out *uiout = current_uiout;
301 int raw_arg = 0;
302 int oind = 0;
303 int skip_unavailable = 0;
304 enum ext_lang_bt_status result = EXT_LANG_BT_ERROR;
305 enum opt
306 {
307 NO_FRAME_FILTERS,
308 SKIP_UNAVAILABLE,
309 };
310 static const struct mi_opt opts[] =
311 {
312 {"-no-frame-filters", NO_FRAME_FILTERS, 0},
313 {"-skip-unavailable", SKIP_UNAVAILABLE, 0},
314 { 0, 0, 0 }
315 };
316
317 while (1)
318 {
319 const char *oarg;
320 int opt = mi_getopt_allow_unknown ("-stack-list-args", argc, argv,
321 opts, &oind, &oarg);
322
323 if (opt < 0)
324 break;
325 switch ((enum opt) opt)
326 {
327 case NO_FRAME_FILTERS:
328 raw_arg = oind;
329 break;
330 case SKIP_UNAVAILABLE:
331 skip_unavailable = 1;
332 break;
333 }
334 }
335
336 if (argc - oind != 1 && argc - oind != 3)
337 error (_("-stack-list-arguments: Usage: " \
338 "[--no-frame-filters] [--skip-unavailable] "
339 "PRINT_VALUES [FRAME_LOW FRAME_HIGH]"));
340
341 if (argc - oind == 3)
342 {
343 frame_low = atoi (argv[1 + oind]);
344 frame_high = atoi (argv[2 + oind]);
345 }
346 else
347 {
348 /* Called with no arguments, it means we want args for the whole
349 backtrace. */
350 frame_low = -1;
351 frame_high = -1;
352 }
353
354 print_values = mi_parse_print_values (argv[oind]);
355
356 /* Let's position fi on the frame at which to start the
357 display. Could be the innermost frame if the whole stack needs
358 displaying, or if frame_low is 0. */
359 for (i = 0, fi = get_current_frame ();
360 fi && i < frame_low;
361 i++, fi = get_prev_frame (fi));
362
363 if (fi == NULL)
364 error (_("-stack-list-arguments: Not enough frames in stack."));
365
366 ui_out_emit_list list_emitter (uiout, "stack-args");
367
368 if (! raw_arg && frame_filters)
369 {
370 frame_filter_flags flags = PRINT_LEVEL | PRINT_ARGS;
371 if (user_frame_print_options.print_raw_frame_arguments)
372 flags |= PRINT_RAW_FRAME_ARGUMENTS;
373 int py_frame_low = frame_low;
374
375 /* We cannot pass -1 to frame_low, as that would signify a
376 relative backtrace from the tail of the stack. So, in the case
377 of frame_low == -1, assign and increment it. */
378 if (py_frame_low == -1)
379 py_frame_low++;
380
381 result = mi_apply_ext_lang_frame_filter (get_current_frame (), flags,
382 print_values, current_uiout,
383 py_frame_low, frame_high);
384 }
385
386 /* Run the inbuilt backtrace if there are no filters registered, or
387 if "--no-frame-filters" has been specified from the command. */
388 if (! frame_filters || raw_arg || result == EXT_LANG_BT_NO_FILTERS)
389 {
390 /* Now let's print the frames up to frame_high, or until there are
391 frames in the stack. */
392 for (;
393 fi && (i <= frame_high || frame_high == -1);
394 i++, fi = get_prev_frame (fi))
395 {
396 QUIT;
397 ui_out_emit_tuple tuple_emitter (uiout, "frame");
398 uiout->field_signed ("level", i);
399 list_args_or_locals (user_frame_print_options,
400 arguments, print_values, fi, skip_unavailable);
401 }
402 }
403}
404
405/* Print a list of the local variables (including arguments) for the
406 current frame. ARGC must be 1 and ARGV[0] specify if only the names,
407 or both names and values of the variables must be printed. See
408 parse_print_value for possible values. */
409
410void
411mi_cmd_stack_list_variables (const char *command, const char *const *argv,
412 int argc)
413{
414 frame_info_ptr frame;
415 int raw_arg = 0;
416 enum ext_lang_bt_status result = EXT_LANG_BT_ERROR;
417 enum print_values print_value;
418 int oind = 0;
419 int skip_unavailable = 0;
420
421 if (argc > 1)
422 {
423 enum opt
424 {
425 NO_FRAME_FILTERS,
426 SKIP_UNAVAILABLE,
427 };
428 static const struct mi_opt opts[] =
429 {
430 {"-no-frame-filters", NO_FRAME_FILTERS, 0},
431 {"-skip-unavailable", SKIP_UNAVAILABLE, 0},
432 { 0, 0, 0 }
433 };
434
435 while (1)
436 {
437 const char *oarg;
438 /* Don't parse 'print-values' as an option. */
439 int opt = mi_getopt ("-stack-list-variables", argc - 1,
440 argv, opts, &oind, &oarg);
441 if (opt < 0)
442 break;
443 switch ((enum opt) opt)
444 {
445 case NO_FRAME_FILTERS:
446 raw_arg = oind;
447 break;
448 case SKIP_UNAVAILABLE:
449 skip_unavailable = 1;
450 break;
451 }
452 }
453 }
454
455 /* After the last option is parsed, there should be only
456 'print-values'. */
457 if (argc - oind != 1)
458 error (_("-stack-list-variables: Usage: [--no-frame-filters] " \
459 "[--skip-unavailable] PRINT_VALUES"));
460
461 frame = get_selected_frame (NULL);
462 print_value = mi_parse_print_values (argv[oind]);
463
464 if (! raw_arg && frame_filters)
465 {
466 frame_filter_flags flags = PRINT_LEVEL | PRINT_ARGS | PRINT_LOCALS;
467 if (user_frame_print_options.print_raw_frame_arguments)
468 flags |= PRINT_RAW_FRAME_ARGUMENTS;
469
470 result = mi_apply_ext_lang_frame_filter (frame, flags,
471 print_value,
472 current_uiout, 0, 0);
473 }
474
475 /* Run the inbuilt backtrace if there are no filters registered, or
476 if "--no-frame-filters" has been specified from the command. */
477 if (! frame_filters || raw_arg || result == EXT_LANG_BT_NO_FILTERS)
478 {
479 list_args_or_locals (user_frame_print_options,
480 all, print_value, frame,
481 skip_unavailable);
482 }
483}
484
485/* Print single local or argument. ARG must be already read in. For
486 WHAT and VALUES see list_args_or_locals.
487
488 Errors are printed as if they would be the parameter value. Use
489 zeroed ARG iff it should not be printed according to VALUES. If
490 SKIP_UNAVAILABLE is true, only print ARG if it is available. */
491
492static void
493list_arg_or_local (const struct frame_arg *arg, enum what_to_list what,
494 enum print_values values, int skip_unavailable,
495 const frame_print_options &fp_opts)
496{
497 struct ui_out *uiout = current_uiout;
498
499 gdb_assert (!arg->val || !arg->error);
500 gdb_assert ((values == PRINT_NO_VALUES && arg->val == NULL
501 && arg->error == NULL)
502 || values == PRINT_SIMPLE_VALUES
503 || (values == PRINT_ALL_VALUES
504 && (arg->val != NULL || arg->error != NULL)));
505 gdb_assert (arg->entry_kind == print_entry_values_no
506 || (arg->entry_kind == print_entry_values_only
507 && (arg->val || arg->error)));
508
509 if (skip_unavailable && arg->val != NULL
510 && (arg->val->entirely_unavailable ()
511 /* A scalar object that does not have all bits available is
512 also considered unavailable, because all bits contribute
513 to its representation. */
514 || (val_print_scalar_type_p (arg->val->type ())
515 && !arg->val->bytes_available (arg->val->embedded_offset (),
516 arg->val->type ()->length ()))))
517 return;
518
519 std::optional<ui_out_emit_tuple> tuple_emitter;
520 if (values != PRINT_NO_VALUES || what == all)
521 tuple_emitter.emplace (uiout, nullptr);
522
523 string_file stb;
524
525 stb.puts (arg->sym->print_name ());
526 if (arg->entry_kind == print_entry_values_only)
527 stb.puts ("@entry");
528 uiout->field_stream ("name", stb);
529
530 if (what == all && arg->sym->is_argument ())
531 uiout->field_signed ("arg", 1);
532
533 if (values == PRINT_SIMPLE_VALUES)
534 {
535 check_typedef (arg->sym->type ());
536 type_print (arg->sym->type (), "", &stb, -1);
537 uiout->field_stream ("type", stb);
538 }
539
540 if (arg->val || arg->error)
541 {
542 if (arg->error)
543 stb.printf (_("<error reading variable: %s>"), arg->error.get ());
544 else
545 {
546 try
547 {
548 struct value_print_options opts;
549
550 get_no_prettyformat_print_options (&opts);
551 opts.deref_ref = true;
552 if (arg->sym->is_argument ())
553 opts.raw = fp_opts.print_raw_frame_arguments;
554 common_val_print (arg->val, &stb, 0, &opts,
555 language_def (arg->sym->language ()));
556 }
557 catch (const gdb_exception_error &except)
558 {
559 stb.printf (_("<error reading variable: %s>"),
560 except.what ());
561 }
562 }
563 uiout->field_stream ("value", stb);
564 }
565}
566
567/* Print a list of the objects for the frame FI in a certain form,
568 which is determined by VALUES. The objects can be locals,
569 arguments or both, which is determined by WHAT. If SKIP_UNAVAILABLE
570 is true, only print the arguments or local variables whose values
571 are available. */
572
573static void
574list_args_or_locals (const frame_print_options &fp_opts,
575 enum what_to_list what, enum print_values values,
576 const frame_info_ptr &fi, int skip_unavailable)
577{
578 const struct block *block;
579 const char *name_of_result;
580 struct ui_out *uiout = current_uiout;
581
582 block = get_frame_block (fi, 0);
583
584 switch (what)
585 {
586 case locals:
587 name_of_result = "locals";
588 break;
589 case arguments:
590 name_of_result = "args";
591 break;
592 case all:
593 name_of_result = "variables";
594 break;
595 default:
596 internal_error ("unexpected what_to_list: %d", (int) what);
597 }
598
599 ui_out_emit_list list_emitter (uiout, name_of_result);
600
601 while (block != 0)
602 {
603 for (struct symbol *sym : block_iterator_range (block))
604 {
605 int print_me = 0;
606
607 switch (sym->aclass ())
608 {
609 default:
610 case LOC_UNDEF: /* catches errors */
611 case LOC_CONST: /* constant */
612 case LOC_TYPEDEF: /* local typedef */
613 case LOC_LABEL: /* local label */
614 case LOC_BLOCK: /* local function */
615 case LOC_CONST_BYTES: /* loc. byte seq. */
616 case LOC_UNRESOLVED: /* unresolved static */
617 case LOC_OPTIMIZED_OUT: /* optimized out */
618 print_me = 0;
619 break;
620
621 case LOC_ARG: /* argument */
622 case LOC_REF_ARG: /* reference arg */
623 case LOC_REGPARM_ADDR: /* indirect register arg */
624 case LOC_LOCAL: /* stack local */
625 case LOC_STATIC: /* static */
626 case LOC_REGISTER: /* register */
627 case LOC_COMPUTED: /* computed location */
628 if (what == all)
629 print_me = 1;
630 else if (what == locals)
631 print_me = !sym->is_argument ();
632 else
633 print_me = sym->is_argument ();
634 break;
635 }
636 if (print_me)
637 {
638 struct symbol *sym2;
639 struct frame_arg arg, entryarg;
640
641 if (sym->is_argument ())
642 sym2 = (lookup_symbol_search_name
643 (sym->search_name (),
644 block, SEARCH_VAR_DOMAIN).symbol);
645 else
646 sym2 = sym;
647 gdb_assert (sym2 != NULL);
648
649 arg.sym = sym2;
650 arg.entry_kind = print_entry_values_no;
651 entryarg.sym = sym2;
652 entryarg.entry_kind = print_entry_values_no;
653
654 switch (values)
655 {
656 case PRINT_SIMPLE_VALUES:
657 if (!mi_simple_type_p (sym2->type ()))
658 break;
659 [[fallthrough]];
660
661 case PRINT_ALL_VALUES:
662 if (sym->is_argument ())
663 read_frame_arg (fp_opts, sym2, fi, &arg, &entryarg);
664 else
665 read_frame_local (sym2, fi, &arg);
666 break;
667 }
668
669 if (arg.entry_kind != print_entry_values_only)
670 list_arg_or_local (&arg, what, values, skip_unavailable,
671 fp_opts);
672 if (entryarg.entry_kind != print_entry_values_no)
673 list_arg_or_local (&entryarg, what, values, skip_unavailable,
674 fp_opts);
675 }
676 }
677
678 if (block->function ())
679 break;
680 else
681 block = block->superblock ();
682 }
683}
684
685/* Read a frame specification from FRAME_EXP and return the selected frame.
686 Call error() if the specification is in any way invalid (so this
687 function never returns NULL).
688
689 The frame specification is usually an integer level number, however if
690 the number does not match a valid frame level then it will be treated as
691 a frame address. The frame address will then be used to find a matching
692 frame in the stack. If no matching frame is found then a new frame will
693 be created.
694
695 The use of FRAME_EXP as an address is undocumented in the GDB user
696 manual, this feature is supported here purely for backward
697 compatibility. */
698
699static frame_info_ptr
700parse_frame_specification (const char *frame_exp)
701{
702 gdb_assert (frame_exp != NULL);
703
704 /* NOTE: Parse and evaluate expression, but do not use
705 functions such as parse_and_eval_long or
706 parse_and_eval_address to also extract the value.
707 Instead value_as_long and value_as_address are used.
708 This avoids problems with expressions that contain
709 side-effects. */
710 struct value *arg = parse_and_eval (frame_exp);
711
712 /* Assume ARG is an integer, and try using that to select a frame. */
713 frame_info_ptr fid;
714 int level = value_as_long (arg);
715
716 fid = find_relative_frame (get_current_frame (), &level);
717 if (level == 0)
718 /* find_relative_frame was successful. */
719 return fid;
720
721 /* Convert the value into a corresponding address. */
722 CORE_ADDR addr = value_as_address (arg);
723
724 /* Assume that ADDR is an address, use that to identify a frame with a
725 matching ID. */
726 struct frame_id id = frame_id_build_wild (addr);
727
728 /* If (s)he specifies the frame with an address, he deserves
729 what (s)he gets. Still, give the highest one that matches.
730 (NOTE: cagney/2004-10-29: Why highest, or outer-most, I don't
731 know). */
732 for (fid = get_current_frame ();
733 fid != NULL;
734 fid = get_prev_frame (fid))
735 {
736 if (id == get_frame_id (fid))
737 {
738 frame_info_ptr prev_frame;
739
740 while (1)
741 {
742 prev_frame = get_prev_frame (fid);
743 if (!prev_frame
744 || id != get_frame_id (prev_frame))
745 break;
746 fid = prev_frame;
747 }
748 return fid;
749 }
750 }
751
752 /* We couldn't identify the frame as an existing frame, but
753 perhaps we can create one with a single argument. */
754 return create_new_frame (addr, 0);
755}
756
757/* Implement the -stack-select-frame MI command. */
758
759void
760mi_cmd_stack_select_frame (const char *command, const char *const *argv,
761 int argc)
762{
763 if (argc == 0 || argc > 1)
764 error (_("-stack-select-frame: Usage: FRAME_SPEC"));
765 select_frame (parse_frame_specification (argv[0]));
766}
767
768void
769mi_cmd_stack_info_frame (const char *command, const char *const *argv,
770 int argc)
771{
772 if (argc > 0)
773 error (_("-stack-info-frame: No arguments allowed"));
774
775 print_frame_info (user_frame_print_options,
776 get_selected_frame (NULL), 1, LOC_AND_ADDRESS, 0, 1);
777}