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