]>
Commit | Line | Data |
---|---|---|
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 | ||
38 | enum what_to_list { locals, arguments, all }; | |
39 | ||
40 | static 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. */ | |
47 | static int frame_filters = 0; | |
48 | ||
49 | void | |
50 | mi_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 | ||
60 | static enum ext_lang_bt_status | |
61 | mi_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 | ||
81 | void | |
82 | mi_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 | ||
185 | void | |
186 | mi_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 | ||
215 | void | |
216 | mi_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 | ||
292 | void | |
293 | mi_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 | ||
410 | void | |
411 | mi_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 | ||
492 | static void | |
493 | list_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 | ||
573 | static void | |
574 | list_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 | ||
699 | static frame_info_ptr | |
700 | parse_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 | ||
759 | void | |
760 | mi_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 | ||
768 | void | |
769 | mi_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 | } |