xref: /openbsd-src/gnu/usr.bin/binutils/gdb/mi/mi-cmd-stack.c (revision 11efff7f3ac2b3cfeff0c0cddc14294d9b3aca4f)
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