Commit | Line | Data |
---|---|---|
fb40c209 | 1 | /* MI Command Set - stack commands. |
61baf725 | 2 | Copyright (C) 2000-2017 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" |
daf3c977 VP |
37 | |
38 | enum what_to_list { locals, arguments, all }; | |
39 | ||
6211c335 | 40 | static void list_args_or_locals (enum what_to_list what, |
bdaf8d4a | 41 | enum print_values values, |
6211c335 YQ |
42 | struct frame_info *fi, |
43 | int skip_unavailable); | |
fb40c209 | 44 | |
1e611234 PM |
45 | /* True if we want to allow Python-based frame filters. */ |
46 | static int frame_filters = 0; | |
47 | ||
48 | void | |
9f33b8b7 | 49 | mi_cmd_enable_frame_filters (const char *command, char **argv, int argc) |
1e611234 PM |
50 | { |
51 | if (argc != 0) | |
52 | error (_("-enable-frame-filters: no arguments allowed")); | |
53 | frame_filters = 1; | |
54 | } | |
55 | ||
10367c7c PA |
56 | /* Like apply_ext_lang_frame_filter, but take a print_values */ |
57 | ||
58 | static enum ext_lang_bt_status | |
59 | mi_apply_ext_lang_frame_filter (struct frame_info *frame, int flags, | |
60 | enum print_values print_values, | |
61 | struct ui_out *out, | |
62 | int frame_low, int frame_high) | |
63 | { | |
64 | /* ext_lang_frame_args's MI options are compatible with MI print | |
65 | values. */ | |
66 | return apply_ext_lang_frame_filter (frame, flags, | |
67 | (enum ext_lang_frame_args) print_values, | |
68 | out, | |
69 | frame_low, frame_high); | |
70 | } | |
71 | ||
2b03b41d | 72 | /* Print a list of the stack frames. Args can be none, in which case |
fb40c209 AC |
73 | we want to print the whole backtrace, or a pair of numbers |
74 | specifying the frame numbers at which to start and stop the | |
2b03b41d SS |
75 | display. If the two numbers are equal, a single frame will be |
76 | displayed. */ | |
77 | ||
ce8f13f8 | 78 | void |
9f33b8b7 | 79 | mi_cmd_stack_list_frames (const char *command, char **argv, int argc) |
fb40c209 AC |
80 | { |
81 | int frame_low; | |
82 | int frame_high; | |
83 | int i; | |
6ad4a2cf | 84 | struct cleanup *cleanup_stack; |
fb40c209 | 85 | struct frame_info *fi; |
6dddc817 | 86 | enum ext_lang_bt_status result = EXT_LANG_BT_ERROR; |
1e611234 PM |
87 | int raw_arg = 0; |
88 | int oind = 0; | |
89 | enum opt | |
90 | { | |
91 | NO_FRAME_FILTERS | |
92 | }; | |
93 | static const struct mi_opt opts[] = | |
94 | { | |
95 | {"-no-frame-filters", NO_FRAME_FILTERS, 0}, | |
96 | { 0, 0, 0 } | |
97 | }; | |
98 | ||
99 | /* Parse arguments. In this instance we are just looking for | |
100 | --no-frame-filters. */ | |
101 | while (1) | |
102 | { | |
103 | char *oarg; | |
104 | int opt = mi_getopt ("-stack-list-frames", argc, argv, | |
105 | opts, &oind, &oarg); | |
106 | if (opt < 0) | |
107 | break; | |
108 | switch ((enum opt) opt) | |
109 | { | |
110 | case NO_FRAME_FILTERS: | |
111 | raw_arg = oind; | |
112 | break; | |
113 | } | |
114 | } | |
fb40c209 | 115 | |
1e611234 PM |
116 | /* After the last option is parsed, there should either be low - |
117 | high range, or no further arguments. */ | |
118 | if ((argc - oind != 0) && (argc - oind != 2)) | |
119 | error (_("-stack-list-frames: Usage: [--no-frame-filters] [FRAME_LOW FRAME_HIGH]")); | |
fb40c209 | 120 | |
1e611234 PM |
121 | /* If there is a range, set it. */ |
122 | if (argc - oind == 2) | |
fb40c209 | 123 | { |
1e611234 PM |
124 | frame_low = atoi (argv[0 + oind]); |
125 | frame_high = atoi (argv[1 + oind]); | |
fb40c209 AC |
126 | } |
127 | else | |
128 | { | |
129 | /* Called with no arguments, it means we want the whole | |
2b03b41d | 130 | backtrace. */ |
fb40c209 AC |
131 | frame_low = -1; |
132 | frame_high = -1; | |
133 | } | |
134 | ||
135 | /* Let's position fi on the frame at which to start the | |
136 | display. Could be the innermost frame if the whole stack needs | |
2b03b41d | 137 | displaying, or if frame_low is 0. */ |
fb40c209 AC |
138 | for (i = 0, fi = get_current_frame (); |
139 | fi && i < frame_low; | |
140 | i++, fi = get_prev_frame (fi)); | |
141 | ||
142 | if (fi == NULL) | |
1b05df00 | 143 | error (_("-stack-list-frames: Not enough frames in stack.")); |
fb40c209 | 144 | |
79a45e25 | 145 | cleanup_stack = make_cleanup_ui_out_list_begin_end (current_uiout, "stack"); |
fb40c209 | 146 | |
1e611234 | 147 | if (! raw_arg && frame_filters) |
fb40c209 | 148 | { |
1e611234 PM |
149 | int flags = PRINT_LEVEL | PRINT_FRAME_INFO; |
150 | int py_frame_low = frame_low; | |
151 | ||
152 | /* We cannot pass -1 to frame_low, as that would signify a | |
153 | relative backtrace from the tail of the stack. So, in the case | |
154 | of frame_low == -1, assign and increment it. */ | |
155 | if (py_frame_low == -1) | |
156 | py_frame_low++; | |
157 | ||
6dddc817 DE |
158 | result = apply_ext_lang_frame_filter (get_current_frame (), flags, |
159 | NO_VALUES, current_uiout, | |
160 | py_frame_low, frame_high); | |
1e611234 PM |
161 | } |
162 | ||
163 | /* Run the inbuilt backtrace if there are no filters registered, or | |
164 | if "--no-frame-filters" has been specified from the command. */ | |
6dddc817 | 165 | if (! frame_filters || raw_arg || result == EXT_LANG_BT_NO_FILTERS) |
1e611234 PM |
166 | { |
167 | /* Now let's print the frames up to frame_high, or until there are | |
168 | frames in the stack. */ | |
169 | for (; | |
170 | fi && (i <= frame_high || frame_high == -1); | |
171 | i++, fi = get_prev_frame (fi)) | |
172 | { | |
173 | QUIT; | |
174 | /* Print the location and the address always, even for level 0. | |
175 | If args is 0, don't print the arguments. */ | |
08d72866 | 176 | print_frame_info (fi, 1, LOC_AND_ADDRESS, 0 /* args */, 0); |
1e611234 | 177 | } |
fb40c209 AC |
178 | } |
179 | ||
6ad4a2cf | 180 | do_cleanups (cleanup_stack); |
fb40c209 AC |
181 | } |
182 | ||
ce8f13f8 | 183 | void |
9f33b8b7 | 184 | mi_cmd_stack_info_depth (const char *command, char **argv, int argc) |
fb40c209 AC |
185 | { |
186 | int frame_high; | |
187 | int i; | |
188 | struct frame_info *fi; | |
189 | ||
fb40c209 | 190 | if (argc > 1) |
1b05df00 | 191 | error (_("-stack-info-depth: Usage: [MAX_DEPTH]")); |
fb40c209 AC |
192 | |
193 | if (argc == 1) | |
194 | frame_high = atoi (argv[0]); | |
195 | else | |
196 | /* Called with no arguments, it means we want the real depth of | |
2b03b41d | 197 | the stack. */ |
fb40c209 AC |
198 | frame_high = -1; |
199 | ||
200 | for (i = 0, fi = get_current_frame (); | |
201 | fi && (i < frame_high || frame_high == -1); | |
202 | i++, fi = get_prev_frame (fi)) | |
203 | QUIT; | |
204 | ||
112e8700 | 205 | current_uiout->field_int ("depth", i); |
fb40c209 AC |
206 | } |
207 | ||
7a93fb82 | 208 | /* Print a list of the locals for the current frame. With argument of |
fb40c209 | 209 | 0, print only the names, with argument of 1 print also the |
2b03b41d SS |
210 | values. */ |
211 | ||
ce8f13f8 | 212 | void |
9f33b8b7 | 213 | mi_cmd_stack_list_locals (const char *command, char **argv, int argc) |
fb40c209 | 214 | { |
f5ec2042 | 215 | struct frame_info *frame; |
1e611234 | 216 | int raw_arg = 0; |
6dddc817 | 217 | enum ext_lang_bt_status result = EXT_LANG_BT_ERROR; |
f486487f | 218 | enum print_values print_value; |
645eab03 | 219 | int oind = 0; |
6211c335 | 220 | int skip_unavailable = 0; |
f5ec2042 | 221 | |
645eab03 YQ |
222 | if (argc > 1) |
223 | { | |
645eab03 YQ |
224 | enum opt |
225 | { | |
6211c335 YQ |
226 | NO_FRAME_FILTERS, |
227 | SKIP_UNAVAILABLE, | |
645eab03 YQ |
228 | }; |
229 | static const struct mi_opt opts[] = | |
230 | { | |
231 | {"-no-frame-filters", NO_FRAME_FILTERS, 0}, | |
6211c335 | 232 | {"-skip-unavailable", SKIP_UNAVAILABLE, 0}, |
645eab03 YQ |
233 | { 0, 0, 0 } |
234 | }; | |
235 | ||
236 | while (1) | |
237 | { | |
238 | char *oarg; | |
239 | /* Don't parse 'print-values' as an option. */ | |
240 | int opt = mi_getopt ("-stack-list-locals", argc - 1, argv, | |
241 | opts, &oind, &oarg); | |
242 | ||
243 | if (opt < 0) | |
244 | break; | |
245 | switch ((enum opt) opt) | |
246 | { | |
247 | case NO_FRAME_FILTERS: | |
248 | raw_arg = oind; | |
6211c335 YQ |
249 | case SKIP_UNAVAILABLE: |
250 | skip_unavailable = 1; | |
645eab03 YQ |
251 | break; |
252 | } | |
253 | } | |
254 | } | |
fb40c209 | 255 | |
645eab03 YQ |
256 | /* After the last option is parsed, there should be only |
257 | 'print-values'. */ | |
258 | if (argc - oind != 1) | |
6211c335 YQ |
259 | error (_("-stack-list-locals: Usage: [--no-frame-filters] " |
260 | "[--skip-unavailable] PRINT_VALUES")); | |
f5ec2042 | 261 | |
1e611234 | 262 | frame = get_selected_frame (NULL); |
645eab03 | 263 | print_value = mi_parse_print_values (argv[oind]); |
1e611234 PM |
264 | |
265 | if (! raw_arg && frame_filters) | |
266 | { | |
267 | int flags = PRINT_LEVEL | PRINT_LOCALS; | |
268 | ||
10367c7c PA |
269 | result = mi_apply_ext_lang_frame_filter (frame, flags, print_value, |
270 | current_uiout, 0, 0); | |
1e611234 PM |
271 | } |
272 | ||
273 | /* Run the inbuilt backtrace if there are no filters registered, or | |
274 | if "--no-frame-filters" has been specified from the command. */ | |
6dddc817 | 275 | if (! frame_filters || raw_arg || result == EXT_LANG_BT_NO_FILTERS) |
1e611234 | 276 | { |
6211c335 YQ |
277 | list_args_or_locals (locals, print_value, frame, |
278 | skip_unavailable); | |
1e611234 | 279 | } |
fb40c209 AC |
280 | } |
281 | ||
7a93fb82 | 282 | /* Print a list of the arguments for the current frame. With argument |
fb40c209 | 283 | of 0, print only the names, with argument of 1 print also the |
2b03b41d SS |
284 | values. */ |
285 | ||
ce8f13f8 | 286 | void |
9f33b8b7 | 287 | mi_cmd_stack_list_args (const char *command, char **argv, int argc) |
fb40c209 AC |
288 | { |
289 | int frame_low; | |
290 | int frame_high; | |
291 | int i; | |
292 | struct frame_info *fi; | |
6ad4a2cf | 293 | struct cleanup *cleanup_stack_args; |
8b777f02 | 294 | enum print_values print_values; |
79a45e25 | 295 | struct ui_out *uiout = current_uiout; |
1e611234 | 296 | int raw_arg = 0; |
242f1fd7 | 297 | int oind = 0; |
6211c335 | 298 | int skip_unavailable = 0; |
6dddc817 | 299 | enum ext_lang_bt_status result = EXT_LANG_BT_ERROR; |
242f1fd7 YQ |
300 | enum opt |
301 | { | |
302 | NO_FRAME_FILTERS, | |
6211c335 | 303 | SKIP_UNAVAILABLE, |
242f1fd7 YQ |
304 | }; |
305 | static const struct mi_opt opts[] = | |
306 | { | |
307 | {"-no-frame-filters", NO_FRAME_FILTERS, 0}, | |
6211c335 | 308 | {"-skip-unavailable", SKIP_UNAVAILABLE, 0}, |
242f1fd7 YQ |
309 | { 0, 0, 0 } |
310 | }; | |
311 | ||
312 | while (1) | |
313 | { | |
314 | char *oarg; | |
315 | int opt = mi_getopt_allow_unknown ("-stack-list-args", argc, argv, | |
316 | opts, &oind, &oarg); | |
fb40c209 | 317 | |
242f1fd7 YQ |
318 | if (opt < 0) |
319 | break; | |
320 | switch ((enum opt) opt) | |
321 | { | |
322 | case NO_FRAME_FILTERS: | |
323 | raw_arg = oind; | |
324 | break; | |
6211c335 YQ |
325 | case SKIP_UNAVAILABLE: |
326 | skip_unavailable = 1; | |
327 | break; | |
242f1fd7 YQ |
328 | } |
329 | } | |
fb40c209 | 330 | |
242f1fd7 YQ |
331 | if (argc - oind != 1 && argc - oind != 3) |
332 | error (_("-stack-list-arguments: Usage: " \ | |
6211c335 YQ |
333 | "[--no-frame-filters] [--skip-unavailable] " |
334 | "PRINT_VALUES [FRAME_LOW FRAME_HIGH]")); | |
1e611234 | 335 | |
242f1fd7 | 336 | if (argc - oind == 3) |
fb40c209 | 337 | { |
242f1fd7 YQ |
338 | frame_low = atoi (argv[1 + oind]); |
339 | frame_high = atoi (argv[2 + oind]); | |
fb40c209 AC |
340 | } |
341 | else | |
342 | { | |
343 | /* Called with no arguments, it means we want args for the whole | |
2b03b41d | 344 | backtrace. */ |
fb40c209 AC |
345 | frame_low = -1; |
346 | frame_high = -1; | |
347 | } | |
348 | ||
242f1fd7 | 349 | print_values = mi_parse_print_values (argv[oind]); |
8b777f02 | 350 | |
fb40c209 AC |
351 | /* Let's position fi on the frame at which to start the |
352 | display. Could be the innermost frame if the whole stack needs | |
2b03b41d | 353 | displaying, or if frame_low is 0. */ |
fb40c209 AC |
354 | for (i = 0, fi = get_current_frame (); |
355 | fi && i < frame_low; | |
356 | i++, fi = get_prev_frame (fi)); | |
357 | ||
358 | if (fi == NULL) | |
1b05df00 | 359 | error (_("-stack-list-arguments: Not enough frames in stack.")); |
fb40c209 | 360 | |
9a2b4c1b MS |
361 | cleanup_stack_args |
362 | = make_cleanup_ui_out_list_begin_end (uiout, "stack-args"); | |
fb40c209 | 363 | |
1e611234 | 364 | if (! raw_arg && frame_filters) |
fb40c209 | 365 | { |
1e611234 PM |
366 | int flags = PRINT_LEVEL | PRINT_ARGS; |
367 | int py_frame_low = frame_low; | |
368 | ||
369 | /* We cannot pass -1 to frame_low, as that would signify a | |
370 | relative backtrace from the tail of the stack. So, in the case | |
371 | of frame_low == -1, assign and increment it. */ | |
372 | if (py_frame_low == -1) | |
373 | py_frame_low++; | |
374 | ||
10367c7c PA |
375 | result = mi_apply_ext_lang_frame_filter (get_current_frame (), flags, |
376 | print_values, current_uiout, | |
377 | py_frame_low, frame_high); | |
fb40c209 AC |
378 | } |
379 | ||
1e611234 PM |
380 | /* Run the inbuilt backtrace if there are no filters registered, or |
381 | if "--no-frame-filters" has been specified from the command. */ | |
6dddc817 | 382 | if (! frame_filters || raw_arg || result == EXT_LANG_BT_NO_FILTERS) |
1e611234 PM |
383 | { |
384 | /* Now let's print the frames up to frame_high, or until there are | |
385 | frames in the stack. */ | |
386 | for (; | |
387 | fi && (i <= frame_high || frame_high == -1); | |
388 | i++, fi = get_prev_frame (fi)) | |
389 | { | |
1e611234 | 390 | QUIT; |
2e783024 | 391 | ui_out_emit_tuple tuple_emitter (uiout, "frame"); |
112e8700 | 392 | uiout->field_int ("level", i); |
6211c335 | 393 | list_args_or_locals (arguments, print_values, fi, skip_unavailable); |
1e611234 PM |
394 | } |
395 | } | |
6ad4a2cf | 396 | do_cleanups (cleanup_stack_args); |
fb40c209 AC |
397 | } |
398 | ||
daf3c977 | 399 | /* Print a list of the local variables (including arguments) for the |
7a93fb82 VP |
400 | current frame. ARGC must be 1 and ARGV[0] specify if only the names, |
401 | or both names and values of the variables must be printed. See | |
402 | parse_print_value for possible values. */ | |
2b03b41d | 403 | |
daf3c977 | 404 | void |
9f33b8b7 | 405 | mi_cmd_stack_list_variables (const char *command, char **argv, int argc) |
daf3c977 VP |
406 | { |
407 | struct frame_info *frame; | |
1e611234 | 408 | int raw_arg = 0; |
6dddc817 | 409 | enum ext_lang_bt_status result = EXT_LANG_BT_ERROR; |
f486487f | 410 | enum print_values print_value; |
645eab03 | 411 | int oind = 0; |
6211c335 | 412 | int skip_unavailable = 0; |
daf3c977 | 413 | |
645eab03 YQ |
414 | if (argc > 1) |
415 | { | |
645eab03 YQ |
416 | enum opt |
417 | { | |
6211c335 YQ |
418 | NO_FRAME_FILTERS, |
419 | SKIP_UNAVAILABLE, | |
645eab03 YQ |
420 | }; |
421 | static const struct mi_opt opts[] = | |
422 | { | |
423 | {"-no-frame-filters", NO_FRAME_FILTERS, 0}, | |
6211c335 | 424 | {"-skip-unavailable", SKIP_UNAVAILABLE, 0}, |
645eab03 YQ |
425 | { 0, 0, 0 } |
426 | }; | |
427 | ||
428 | while (1) | |
429 | { | |
430 | char *oarg; | |
431 | /* Don't parse 'print-values' as an option. */ | |
432 | int opt = mi_getopt ("-stack-list-variables", argc - 1, | |
433 | argv, opts, &oind, &oarg); | |
434 | if (opt < 0) | |
435 | break; | |
436 | switch ((enum opt) opt) | |
437 | { | |
438 | case NO_FRAME_FILTERS: | |
439 | raw_arg = oind; | |
440 | break; | |
6211c335 YQ |
441 | case SKIP_UNAVAILABLE: |
442 | skip_unavailable = 1; | |
443 | break; | |
645eab03 YQ |
444 | } |
445 | } | |
446 | } | |
daf3c977 | 447 | |
645eab03 YQ |
448 | /* After the last option is parsed, there should be only |
449 | 'print-values'. */ | |
450 | if (argc - oind != 1) | |
6211c335 YQ |
451 | error (_("-stack-list-variables: Usage: [--no-frame-filters] " \ |
452 | "[--skip-unavailable] PRINT_VALUES")); | |
daf3c977 | 453 | |
1e611234 | 454 | frame = get_selected_frame (NULL); |
645eab03 | 455 | print_value = mi_parse_print_values (argv[oind]); |
1e611234 PM |
456 | |
457 | if (! raw_arg && frame_filters) | |
458 | { | |
459 | int flags = PRINT_LEVEL | PRINT_ARGS | PRINT_LOCALS; | |
460 | ||
10367c7c PA |
461 | result = mi_apply_ext_lang_frame_filter (frame, flags, |
462 | print_value, | |
463 | current_uiout, 0, 0); | |
1e611234 PM |
464 | } |
465 | ||
466 | /* Run the inbuilt backtrace if there are no filters registered, or | |
467 | if "--no-frame-filters" has been specified from the command. */ | |
6dddc817 | 468 | if (! frame_filters || raw_arg || result == EXT_LANG_BT_NO_FILTERS) |
1e611234 | 469 | { |
6211c335 YQ |
470 | list_args_or_locals (all, print_value, frame, |
471 | skip_unavailable); | |
1e611234 | 472 | } |
daf3c977 VP |
473 | } |
474 | ||
2b03b41d SS |
475 | /* Print single local or argument. ARG must be already read in. For |
476 | WHAT and VALUES see list_args_or_locals. | |
93d86cef | 477 | |
2b03b41d | 478 | Errors are printed as if they would be the parameter value. Use |
6211c335 YQ |
479 | zeroed ARG iff it should not be printed according to VALUES. If |
480 | SKIP_UNAVAILABLE is true, only print ARG if it is available. */ | |
93d86cef JK |
481 | |
482 | static void | |
483 | list_arg_or_local (const struct frame_arg *arg, enum what_to_list what, | |
6211c335 | 484 | enum print_values values, int skip_unavailable) |
93d86cef | 485 | { |
f99d8bf4 | 486 | struct cleanup *old_chain; |
93d86cef | 487 | struct ui_out *uiout = current_uiout; |
f99d8bf4 | 488 | |
93d86cef JK |
489 | gdb_assert (!arg->val || !arg->error); |
490 | gdb_assert ((values == PRINT_NO_VALUES && arg->val == NULL | |
491 | && arg->error == NULL) | |
492 | || values == PRINT_SIMPLE_VALUES | |
493 | || (values == PRINT_ALL_VALUES | |
494 | && (arg->val != NULL || arg->error != NULL))); | |
e18b2753 JK |
495 | gdb_assert (arg->entry_kind == print_entry_values_no |
496 | || (arg->entry_kind == print_entry_values_only | |
497 | && (arg->val || arg->error))); | |
93d86cef | 498 | |
6211c335 YQ |
499 | if (skip_unavailable && arg->val != NULL |
500 | && (value_entirely_unavailable (arg->val) | |
501 | /* A scalar object that does not have all bits available is | |
502 | also considered unavailable, because all bits contribute | |
503 | to its representation. */ | |
504 | || (val_print_scalar_type_p (value_type (arg->val)) | |
505 | && !value_bytes_available (arg->val, | |
506 | value_embedded_offset (arg->val), | |
507 | TYPE_LENGTH (value_type (arg->val)))))) | |
508 | return; | |
509 | ||
d7e74731 | 510 | old_chain = make_cleanup (null_cleanup, NULL); |
6211c335 | 511 | |
93d86cef | 512 | if (values != PRINT_NO_VALUES || what == all) |
cd82eddc | 513 | make_cleanup_ui_out_tuple_begin_end (uiout, NULL); |
93d86cef | 514 | |
d7e74731 PA |
515 | string_file stb; |
516 | ||
517 | stb.puts (SYMBOL_PRINT_NAME (arg->sym)); | |
e18b2753 | 518 | if (arg->entry_kind == print_entry_values_only) |
d7e74731 | 519 | stb.puts ("@entry"); |
112e8700 | 520 | uiout->field_stream ("name", stb); |
93d86cef JK |
521 | |
522 | if (what == all && SYMBOL_IS_ARGUMENT (arg->sym)) | |
112e8700 | 523 | uiout->field_int ("arg", 1); |
93d86cef JK |
524 | |
525 | if (values == PRINT_SIMPLE_VALUES) | |
526 | { | |
527 | check_typedef (arg->sym->type); | |
d7e74731 | 528 | type_print (arg->sym->type, "", &stb, -1); |
112e8700 | 529 | uiout->field_stream ("type", stb); |
93d86cef JK |
530 | } |
531 | ||
532 | if (arg->val || arg->error) | |
533 | { | |
492d29ea | 534 | const char *error_message = NULL; |
93d86cef JK |
535 | |
536 | if (arg->error) | |
492d29ea | 537 | error_message = arg->error; |
93d86cef JK |
538 | else |
539 | { | |
492d29ea | 540 | TRY |
93d86cef JK |
541 | { |
542 | struct value_print_options opts; | |
543 | ||
2a998fc0 | 544 | get_no_prettyformat_print_options (&opts); |
93d86cef | 545 | opts.deref_ref = 1; |
d7e74731 | 546 | common_val_print (arg->val, &stb, 0, &opts, |
93d86cef JK |
547 | language_def (SYMBOL_LANGUAGE (arg->sym))); |
548 | } | |
492d29ea PA |
549 | CATCH (except, RETURN_MASK_ERROR) |
550 | { | |
551 | error_message = except.message; | |
552 | } | |
553 | END_CATCH | |
93d86cef | 554 | } |
492d29ea | 555 | if (error_message != NULL) |
d7e74731 | 556 | stb.printf (_("<error reading variable: %s>"), error_message); |
112e8700 | 557 | uiout->field_stream ("value", stb); |
93d86cef JK |
558 | } |
559 | ||
f99d8bf4 | 560 | do_cleanups (old_chain); |
93d86cef | 561 | } |
daf3c977 | 562 | |
5c4aa40b YQ |
563 | /* Print a list of the objects for the frame FI in a certain form, |
564 | which is determined by VALUES. The objects can be locals, | |
6211c335 YQ |
565 | arguments or both, which is determined by WHAT. If SKIP_UNAVAILABLE |
566 | is true, only print the arguments or local variables whose values | |
567 | are available. */ | |
2b03b41d | 568 | |
fb40c209 | 569 | static void |
bdaf8d4a | 570 | list_args_or_locals (enum what_to_list what, enum print_values values, |
6211c335 | 571 | struct frame_info *fi, int skip_unavailable) |
fb40c209 | 572 | { |
3977b71f | 573 | const struct block *block; |
fb40c209 | 574 | struct symbol *sym; |
8157b174 | 575 | struct block_iterator iter; |
6ad4a2cf | 576 | struct cleanup *cleanup_list; |
f5ec2042 | 577 | struct type *type; |
a121b7c1 | 578 | const char *name_of_result; |
79a45e25 | 579 | struct ui_out *uiout = current_uiout; |
fb40c209 | 580 | |
ae767bfb | 581 | block = get_frame_block (fi, 0); |
fb40c209 | 582 | |
daf3c977 VP |
583 | switch (what) |
584 | { | |
585 | case locals: | |
d6fd4674 PA |
586 | name_of_result = "locals"; |
587 | break; | |
daf3c977 | 588 | case arguments: |
d6fd4674 PA |
589 | name_of_result = "args"; |
590 | break; | |
daf3c977 | 591 | case all: |
d6fd4674 PA |
592 | name_of_result = "variables"; |
593 | break; | |
654e7c1f | 594 | default: |
d6fd4674 PA |
595 | internal_error (__FILE__, __LINE__, |
596 | "unexpected what_to_list: %d", (int) what); | |
daf3c977 VP |
597 | } |
598 | ||
599 | cleanup_list = make_cleanup_ui_out_list_begin_end (uiout, name_of_result); | |
fb40c209 AC |
600 | |
601 | while (block != 0) | |
602 | { | |
de4f826b | 603 | ALL_BLOCK_SYMBOLS (block, iter, sym) |
fb40c209 | 604 | { |
39bf4652 JB |
605 | int print_me = 0; |
606 | ||
fb40c209 AC |
607 | switch (SYMBOL_CLASS (sym)) |
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 */ | |
fb40c209 | 623 | case LOC_REGPARM_ADDR: /* indirect register arg */ |
fb40c209 | 624 | case LOC_LOCAL: /* stack local */ |
fb40c209 AC |
625 | case LOC_STATIC: /* static */ |
626 | case LOC_REGISTER: /* register */ | |
4cf623b6 | 627 | case LOC_COMPUTED: /* computed location */ |
daf3c977 | 628 | if (what == all) |
fb40c209 | 629 | print_me = 1; |
daf3c977 VP |
630 | else if (what == locals) |
631 | print_me = !SYMBOL_IS_ARGUMENT (sym); | |
632 | else | |
633 | print_me = SYMBOL_IS_ARGUMENT (sym); | |
fb40c209 AC |
634 | break; |
635 | } | |
636 | if (print_me) | |
637 | { | |
6bb0384f | 638 | struct symbol *sym2; |
e18b2753 | 639 | struct frame_arg arg, entryarg; |
fb40c209 | 640 | |
daf3c977 | 641 | if (SYMBOL_IS_ARGUMENT (sym)) |
f7e44f65 | 642 | sym2 = lookup_symbol (SYMBOL_LINKAGE_NAME (sym), |
f5ec2042 | 643 | block, VAR_DOMAIN, |
d12307c1 | 644 | NULL).symbol; |
f5ec2042 | 645 | else |
2a2d4dc3 | 646 | sym2 = sym; |
f7e44f65 | 647 | gdb_assert (sym2 != NULL); |
93d86cef JK |
648 | |
649 | memset (&arg, 0, sizeof (arg)); | |
650 | arg.sym = sym2; | |
e18b2753 JK |
651 | arg.entry_kind = print_entry_values_no; |
652 | memset (&entryarg, 0, sizeof (entryarg)); | |
653 | entryarg.sym = sym2; | |
654 | entryarg.entry_kind = print_entry_values_no; | |
93d86cef | 655 | |
f5ec2042 NR |
656 | switch (values) |
657 | { | |
658 | case PRINT_SIMPLE_VALUES: | |
659 | type = check_typedef (sym2->type); | |
f5ec2042 NR |
660 | if (TYPE_CODE (type) != TYPE_CODE_ARRAY |
661 | && TYPE_CODE (type) != TYPE_CODE_STRUCT | |
662 | && TYPE_CODE (type) != TYPE_CODE_UNION) | |
663 | { | |
f5ec2042 | 664 | case PRINT_ALL_VALUES: |
82a0a75f YQ |
665 | if (SYMBOL_IS_ARGUMENT (sym)) |
666 | read_frame_arg (sym2, fi, &arg, &entryarg); | |
667 | else | |
668 | read_frame_local (sym2, fi, &arg); | |
93d86cef | 669 | } |
f5ec2042 | 670 | break; |
fb40c209 | 671 | } |
7a93fb82 | 672 | |
e18b2753 | 673 | if (arg.entry_kind != print_entry_values_only) |
6211c335 | 674 | list_arg_or_local (&arg, what, values, skip_unavailable); |
e18b2753 | 675 | if (entryarg.entry_kind != print_entry_values_no) |
6211c335 | 676 | list_arg_or_local (&entryarg, what, values, skip_unavailable); |
93d86cef | 677 | xfree (arg.error); |
e18b2753 | 678 | xfree (entryarg.error); |
fb40c209 AC |
679 | } |
680 | } | |
2b03b41d | 681 | |
fb40c209 AC |
682 | if (BLOCK_FUNCTION (block)) |
683 | break; | |
684 | else | |
685 | block = BLOCK_SUPERBLOCK (block); | |
686 | } | |
6ad4a2cf | 687 | do_cleanups (cleanup_list); |
fb40c209 AC |
688 | } |
689 | ||
ce8f13f8 | 690 | void |
9f33b8b7 | 691 | mi_cmd_stack_select_frame (const char *command, char **argv, int argc) |
fb40c209 | 692 | { |
fcf43932 | 693 | if (argc == 0 || argc > 1) |
1b05df00 | 694 | error (_("-stack-select-frame: Usage: FRAME_SPEC")); |
fb40c209 | 695 | |
fcf43932 | 696 | select_frame_command (argv[0], 1 /* not used */ ); |
fb40c209 | 697 | } |
64fd8944 | 698 | |
ce8f13f8 | 699 | void |
9f33b8b7 | 700 | mi_cmd_stack_info_frame (const char *command, char **argv, int argc) |
64fd8944 NR |
701 | { |
702 | if (argc > 0) | |
2b03b41d | 703 | error (_("-stack-info-frame: No arguments allowed")); |
ce8f13f8 | 704 | |
08d72866 | 705 | print_frame_info (get_selected_frame (NULL), 1, LOC_AND_ADDRESS, 0, 1); |
64fd8944 | 706 | } |