1b725ae77Skettenis /* MI Command Set - stack commands.
2b725ae77Skettenis Copyright 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
3b725ae77Skettenis Contributed by Cygnus Solutions (a Red Hat company).
4b725ae77Skettenis
5b725ae77Skettenis This file is part of GDB.
6b725ae77Skettenis
7b725ae77Skettenis This program is free software; you can redistribute it and/or modify
8b725ae77Skettenis it under the terms of the GNU General Public License as published by
9b725ae77Skettenis the Free Software Foundation; either version 2 of the License, or
10b725ae77Skettenis (at your option) any later version.
11b725ae77Skettenis
12b725ae77Skettenis This program is distributed in the hope that it will be useful,
13b725ae77Skettenis but WITHOUT ANY WARRANTY; without even the implied warranty of
14b725ae77Skettenis MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15b725ae77Skettenis GNU General Public License for more details.
16b725ae77Skettenis
17b725ae77Skettenis You should have received a copy of the GNU General Public License
18b725ae77Skettenis along with this program; if not, write to the Free Software
19b725ae77Skettenis Foundation, Inc., 59 Temple Place - Suite 330,
20b725ae77Skettenis Boston, MA 02111-1307, USA. */
21b725ae77Skettenis
22b725ae77Skettenis #include "defs.h"
23b725ae77Skettenis #include "target.h"
24b725ae77Skettenis #include "frame.h"
25b725ae77Skettenis #include "value.h"
26b725ae77Skettenis #include "mi-cmds.h"
27b725ae77Skettenis #include "ui-out.h"
28b725ae77Skettenis #include "symtab.h"
29b725ae77Skettenis #include "block.h"
30b725ae77Skettenis #include "stack.h"
31b725ae77Skettenis #include "dictionary.h"
32b725ae77Skettenis #include "gdb_string.h"
33b725ae77Skettenis
34b725ae77Skettenis static void list_args_or_locals (int locals, int values, struct frame_info *fi);
35b725ae77Skettenis
36b725ae77Skettenis /* Print a list of the stack frames. Args can be none, in which case
37b725ae77Skettenis we want to print the whole backtrace, or a pair of numbers
38b725ae77Skettenis specifying the frame numbers at which to start and stop the
39b725ae77Skettenis display. If the two numbers are equal, a single frame will be
40b725ae77Skettenis displayed. */
41b725ae77Skettenis enum mi_cmd_result
mi_cmd_stack_list_frames(char * command,char ** argv,int argc)42b725ae77Skettenis mi_cmd_stack_list_frames (char *command, char **argv, int argc)
43b725ae77Skettenis {
44b725ae77Skettenis int frame_low;
45b725ae77Skettenis int frame_high;
46b725ae77Skettenis int i;
47b725ae77Skettenis struct cleanup *cleanup_stack;
48b725ae77Skettenis struct frame_info *fi;
49b725ae77Skettenis
50b725ae77Skettenis if (!target_has_stack)
51b725ae77Skettenis error ("mi_cmd_stack_list_frames: No stack.");
52b725ae77Skettenis
53b725ae77Skettenis if (argc > 2 || argc == 1)
54b725ae77Skettenis error ("mi_cmd_stack_list_frames: Usage: [FRAME_LOW FRAME_HIGH]");
55b725ae77Skettenis
56b725ae77Skettenis if (argc == 2)
57b725ae77Skettenis {
58b725ae77Skettenis frame_low = atoi (argv[0]);
59b725ae77Skettenis frame_high = atoi (argv[1]);
60b725ae77Skettenis }
61b725ae77Skettenis else
62b725ae77Skettenis {
63b725ae77Skettenis /* Called with no arguments, it means we want the whole
64b725ae77Skettenis backtrace. */
65b725ae77Skettenis frame_low = -1;
66b725ae77Skettenis frame_high = -1;
67b725ae77Skettenis }
68b725ae77Skettenis
69b725ae77Skettenis /* Let's position fi on the frame at which to start the
70b725ae77Skettenis display. Could be the innermost frame if the whole stack needs
71b725ae77Skettenis displaying, or if frame_low is 0. */
72b725ae77Skettenis for (i = 0, fi = get_current_frame ();
73b725ae77Skettenis fi && i < frame_low;
74b725ae77Skettenis i++, fi = get_prev_frame (fi));
75b725ae77Skettenis
76b725ae77Skettenis if (fi == NULL)
77b725ae77Skettenis error ("mi_cmd_stack_list_frames: Not enough frames in stack.");
78b725ae77Skettenis
79b725ae77Skettenis cleanup_stack = make_cleanup_ui_out_list_begin_end (uiout, "stack");
80b725ae77Skettenis
81b725ae77Skettenis /* Now let;s print the frames up to frame_high, or until there are
82b725ae77Skettenis frames in the stack. */
83b725ae77Skettenis for (;
84b725ae77Skettenis fi && (i <= frame_high || frame_high == -1);
85b725ae77Skettenis i++, fi = get_prev_frame (fi))
86b725ae77Skettenis {
87b725ae77Skettenis QUIT;
88*11efff7fSkettenis /* Print the location and the address always, even for level 0.
89b725ae77Skettenis args == 0: don't print the arguments. */
90*11efff7fSkettenis print_frame_info (fi, 1, LOC_AND_ADDRESS, 0 /* args */ );
91b725ae77Skettenis }
92b725ae77Skettenis
93b725ae77Skettenis do_cleanups (cleanup_stack);
94b725ae77Skettenis if (i < frame_high)
95b725ae77Skettenis error ("mi_cmd_stack_list_frames: Not enough frames in stack.");
96b725ae77Skettenis
97b725ae77Skettenis return MI_CMD_DONE;
98b725ae77Skettenis }
99b725ae77Skettenis
100b725ae77Skettenis enum mi_cmd_result
mi_cmd_stack_info_depth(char * command,char ** argv,int argc)101b725ae77Skettenis mi_cmd_stack_info_depth (char *command, char **argv, int argc)
102b725ae77Skettenis {
103b725ae77Skettenis int frame_high;
104b725ae77Skettenis int i;
105b725ae77Skettenis struct frame_info *fi;
106b725ae77Skettenis
107b725ae77Skettenis if (!target_has_stack)
108b725ae77Skettenis error ("mi_cmd_stack_info_depth: No stack.");
109b725ae77Skettenis
110b725ae77Skettenis if (argc > 1)
111b725ae77Skettenis error ("mi_cmd_stack_info_depth: Usage: [MAX_DEPTH]");
112b725ae77Skettenis
113b725ae77Skettenis if (argc == 1)
114b725ae77Skettenis frame_high = atoi (argv[0]);
115b725ae77Skettenis else
116b725ae77Skettenis /* Called with no arguments, it means we want the real depth of
117b725ae77Skettenis the stack. */
118b725ae77Skettenis frame_high = -1;
119b725ae77Skettenis
120b725ae77Skettenis for (i = 0, fi = get_current_frame ();
121b725ae77Skettenis fi && (i < frame_high || frame_high == -1);
122b725ae77Skettenis i++, fi = get_prev_frame (fi))
123b725ae77Skettenis QUIT;
124b725ae77Skettenis
125b725ae77Skettenis ui_out_field_int (uiout, "depth", i);
126b725ae77Skettenis
127b725ae77Skettenis return MI_CMD_DONE;
128b725ae77Skettenis }
129b725ae77Skettenis
130b725ae77Skettenis /* Print a list of the locals for the current frame. With argument of
131b725ae77Skettenis 0, print only the names, with argument of 1 print also the
132b725ae77Skettenis values. */
133b725ae77Skettenis enum mi_cmd_result
mi_cmd_stack_list_locals(char * command,char ** argv,int argc)134b725ae77Skettenis mi_cmd_stack_list_locals (char *command, char **argv, int argc)
135b725ae77Skettenis {
136b725ae77Skettenis struct frame_info *frame;
137b725ae77Skettenis enum print_values print_values;
138b725ae77Skettenis
139b725ae77Skettenis if (argc != 1)
140b725ae77Skettenis error ("mi_cmd_stack_list_locals: Usage: PRINT_VALUES");
141b725ae77Skettenis
142b725ae77Skettenis frame = get_selected_frame ();
143b725ae77Skettenis
144b725ae77Skettenis if (strcmp (argv[0], "0") == 0
145b725ae77Skettenis || strcmp (argv[0], "--no-values") == 0)
146b725ae77Skettenis print_values = PRINT_NO_VALUES;
147b725ae77Skettenis else if (strcmp (argv[0], "1") == 0
148b725ae77Skettenis || strcmp (argv[0], "--all-values") == 0)
149b725ae77Skettenis print_values = PRINT_ALL_VALUES;
150b725ae77Skettenis else if (strcmp (argv[0], "2") == 0
151b725ae77Skettenis || strcmp (argv[0], "--simple-values") == 0)
152b725ae77Skettenis print_values = PRINT_SIMPLE_VALUES;
153b725ae77Skettenis else
154b725ae77Skettenis error ("Unknown value for PRINT_VALUES: must be: 0 or \"--no-values\", 1 or \"--all-values\", 2 or \"--simple-values\"");
155b725ae77Skettenis list_args_or_locals (1, print_values, frame);
156b725ae77Skettenis return MI_CMD_DONE;
157b725ae77Skettenis }
158b725ae77Skettenis
159b725ae77Skettenis /* Print a list of the arguments for the current frame. With argument
160b725ae77Skettenis of 0, print only the names, with argument of 1 print also the
161b725ae77Skettenis values. */
162b725ae77Skettenis enum mi_cmd_result
mi_cmd_stack_list_args(char * command,char ** argv,int argc)163b725ae77Skettenis mi_cmd_stack_list_args (char *command, char **argv, int argc)
164b725ae77Skettenis {
165b725ae77Skettenis int frame_low;
166b725ae77Skettenis int frame_high;
167b725ae77Skettenis int i;
168b725ae77Skettenis struct frame_info *fi;
169b725ae77Skettenis struct cleanup *cleanup_stack_args;
170b725ae77Skettenis
171b725ae77Skettenis if (argc < 1 || argc > 3 || argc == 2)
172b725ae77Skettenis error ("mi_cmd_stack_list_args: Usage: PRINT_VALUES [FRAME_LOW FRAME_HIGH]");
173b725ae77Skettenis
174b725ae77Skettenis if (argc == 3)
175b725ae77Skettenis {
176b725ae77Skettenis frame_low = atoi (argv[1]);
177b725ae77Skettenis frame_high = atoi (argv[2]);
178b725ae77Skettenis }
179b725ae77Skettenis else
180b725ae77Skettenis {
181b725ae77Skettenis /* Called with no arguments, it means we want args for the whole
182b725ae77Skettenis backtrace. */
183b725ae77Skettenis frame_low = -1;
184b725ae77Skettenis frame_high = -1;
185b725ae77Skettenis }
186b725ae77Skettenis
187b725ae77Skettenis /* Let's position fi on the frame at which to start the
188b725ae77Skettenis display. Could be the innermost frame if the whole stack needs
189b725ae77Skettenis displaying, or if frame_low is 0. */
190b725ae77Skettenis for (i = 0, fi = get_current_frame ();
191b725ae77Skettenis fi && i < frame_low;
192b725ae77Skettenis i++, fi = get_prev_frame (fi));
193b725ae77Skettenis
194b725ae77Skettenis if (fi == NULL)
195b725ae77Skettenis error ("mi_cmd_stack_list_args: Not enough frames in stack.");
196b725ae77Skettenis
197b725ae77Skettenis cleanup_stack_args = make_cleanup_ui_out_list_begin_end (uiout, "stack-args");
198b725ae77Skettenis
199b725ae77Skettenis /* Now let's print the frames up to frame_high, or until there are
200b725ae77Skettenis frames in the stack. */
201b725ae77Skettenis for (;
202b725ae77Skettenis fi && (i <= frame_high || frame_high == -1);
203b725ae77Skettenis i++, fi = get_prev_frame (fi))
204b725ae77Skettenis {
205b725ae77Skettenis struct cleanup *cleanup_frame;
206b725ae77Skettenis QUIT;
207b725ae77Skettenis cleanup_frame = make_cleanup_ui_out_tuple_begin_end (uiout, "frame");
208b725ae77Skettenis ui_out_field_int (uiout, "level", i);
209b725ae77Skettenis list_args_or_locals (0, atoi (argv[0]), fi);
210b725ae77Skettenis do_cleanups (cleanup_frame);
211b725ae77Skettenis }
212b725ae77Skettenis
213b725ae77Skettenis do_cleanups (cleanup_stack_args);
214b725ae77Skettenis if (i < frame_high)
215b725ae77Skettenis error ("mi_cmd_stack_list_args: Not enough frames in stack.");
216b725ae77Skettenis
217b725ae77Skettenis return MI_CMD_DONE;
218b725ae77Skettenis }
219b725ae77Skettenis
220b725ae77Skettenis /* Print a list of the locals or the arguments for the currently
221b725ae77Skettenis selected frame. If the argument passed is 0, printonly the names
222b725ae77Skettenis of the variables, if an argument of 1 is passed, print the values
223b725ae77Skettenis as well. */
224b725ae77Skettenis static void
list_args_or_locals(int locals,int values,struct frame_info * fi)225b725ae77Skettenis list_args_or_locals (int locals, int values, struct frame_info *fi)
226b725ae77Skettenis {
227b725ae77Skettenis struct block *block;
228b725ae77Skettenis struct symbol *sym;
229b725ae77Skettenis struct dict_iterator iter;
230b725ae77Skettenis int nsyms;
231b725ae77Skettenis struct cleanup *cleanup_list;
232b725ae77Skettenis static struct ui_stream *stb = NULL;
233b725ae77Skettenis struct type *type;
234b725ae77Skettenis
235b725ae77Skettenis stb = ui_out_stream_new (uiout);
236b725ae77Skettenis
237b725ae77Skettenis block = get_frame_block (fi, 0);
238b725ae77Skettenis
239b725ae77Skettenis cleanup_list = make_cleanup_ui_out_list_begin_end (uiout, locals ? "locals" : "args");
240b725ae77Skettenis
241b725ae77Skettenis while (block != 0)
242b725ae77Skettenis {
243b725ae77Skettenis ALL_BLOCK_SYMBOLS (block, iter, sym)
244b725ae77Skettenis {
245b725ae77Skettenis int print_me = 0;
246b725ae77Skettenis
247b725ae77Skettenis switch (SYMBOL_CLASS (sym))
248b725ae77Skettenis {
249b725ae77Skettenis default:
250b725ae77Skettenis case LOC_UNDEF: /* catches errors */
251b725ae77Skettenis case LOC_CONST: /* constant */
252b725ae77Skettenis case LOC_TYPEDEF: /* local typedef */
253b725ae77Skettenis case LOC_LABEL: /* local label */
254b725ae77Skettenis case LOC_BLOCK: /* local function */
255b725ae77Skettenis case LOC_CONST_BYTES: /* loc. byte seq. */
256b725ae77Skettenis case LOC_UNRESOLVED: /* unresolved static */
257b725ae77Skettenis case LOC_OPTIMIZED_OUT: /* optimized out */
258b725ae77Skettenis print_me = 0;
259b725ae77Skettenis break;
260b725ae77Skettenis
261b725ae77Skettenis case LOC_ARG: /* argument */
262b725ae77Skettenis case LOC_REF_ARG: /* reference arg */
263b725ae77Skettenis case LOC_REGPARM: /* register arg */
264b725ae77Skettenis case LOC_REGPARM_ADDR: /* indirect register arg */
265b725ae77Skettenis case LOC_LOCAL_ARG: /* stack arg */
266b725ae77Skettenis case LOC_BASEREG_ARG: /* basereg arg */
267b725ae77Skettenis case LOC_COMPUTED_ARG: /* arg with computed location */
268b725ae77Skettenis if (!locals)
269b725ae77Skettenis print_me = 1;
270b725ae77Skettenis break;
271b725ae77Skettenis
272b725ae77Skettenis case LOC_LOCAL: /* stack local */
273b725ae77Skettenis case LOC_BASEREG: /* basereg local */
274b725ae77Skettenis case LOC_STATIC: /* static */
275b725ae77Skettenis case LOC_REGISTER: /* register */
276b725ae77Skettenis case LOC_COMPUTED: /* computed location */
277b725ae77Skettenis if (locals)
278b725ae77Skettenis print_me = 1;
279b725ae77Skettenis break;
280b725ae77Skettenis }
281b725ae77Skettenis if (print_me)
282b725ae77Skettenis {
283b725ae77Skettenis struct cleanup *cleanup_tuple = NULL;
284b725ae77Skettenis struct symbol *sym2;
285b725ae77Skettenis if (values != PRINT_NO_VALUES)
286b725ae77Skettenis cleanup_tuple =
287b725ae77Skettenis make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
288b725ae77Skettenis ui_out_field_string (uiout, "name", SYMBOL_PRINT_NAME (sym));
289b725ae77Skettenis
290b725ae77Skettenis if (!locals)
291b725ae77Skettenis sym2 = lookup_symbol (SYMBOL_NATURAL_NAME (sym),
292b725ae77Skettenis block, VAR_DOMAIN,
293b725ae77Skettenis (int *) NULL,
294b725ae77Skettenis (struct symtab **) NULL);
295b725ae77Skettenis else
296b725ae77Skettenis sym2 = sym;
297b725ae77Skettenis switch (values)
298b725ae77Skettenis {
299b725ae77Skettenis case PRINT_SIMPLE_VALUES:
300b725ae77Skettenis type = check_typedef (sym2->type);
301b725ae77Skettenis type_print (sym2->type, "", stb->stream, -1);
302b725ae77Skettenis ui_out_field_stream (uiout, "type", stb);
303b725ae77Skettenis if (TYPE_CODE (type) != TYPE_CODE_ARRAY
304b725ae77Skettenis && TYPE_CODE (type) != TYPE_CODE_STRUCT
305b725ae77Skettenis && TYPE_CODE (type) != TYPE_CODE_UNION)
306b725ae77Skettenis {
307b725ae77Skettenis print_variable_value (sym2, fi, stb->stream);
308b725ae77Skettenis ui_out_field_stream (uiout, "value", stb);
309b725ae77Skettenis }
310b725ae77Skettenis do_cleanups (cleanup_tuple);
311b725ae77Skettenis break;
312b725ae77Skettenis case PRINT_ALL_VALUES:
313b725ae77Skettenis print_variable_value (sym2, fi, stb->stream);
314b725ae77Skettenis ui_out_field_stream (uiout, "value", stb);
315b725ae77Skettenis do_cleanups (cleanup_tuple);
316b725ae77Skettenis break;
317b725ae77Skettenis }
318b725ae77Skettenis }
319b725ae77Skettenis }
320b725ae77Skettenis if (BLOCK_FUNCTION (block))
321b725ae77Skettenis break;
322b725ae77Skettenis else
323b725ae77Skettenis block = BLOCK_SUPERBLOCK (block);
324b725ae77Skettenis }
325b725ae77Skettenis do_cleanups (cleanup_list);
326b725ae77Skettenis ui_out_stream_delete (stb);
327b725ae77Skettenis }
328b725ae77Skettenis
329b725ae77Skettenis enum mi_cmd_result
mi_cmd_stack_select_frame(char * command,char ** argv,int argc)330b725ae77Skettenis mi_cmd_stack_select_frame (char *command, char **argv, int argc)
331b725ae77Skettenis {
332b725ae77Skettenis if (!target_has_stack)
333b725ae77Skettenis error ("mi_cmd_stack_select_frame: No stack.");
334b725ae77Skettenis
335b725ae77Skettenis if (argc > 1)
336b725ae77Skettenis error ("mi_cmd_stack_select_frame: Usage: [FRAME_SPEC]");
337b725ae77Skettenis
338b725ae77Skettenis /* with no args, don't change frame */
339b725ae77Skettenis if (argc == 0)
340b725ae77Skettenis select_frame_command (0, 1 /* not used */ );
341b725ae77Skettenis else
342b725ae77Skettenis select_frame_command (argv[0], 1 /* not used */ );
343b725ae77Skettenis return MI_CMD_DONE;
344b725ae77Skettenis }
345