198944Sobrien/* MI Command Set - stack commands. 2130803Smarcel Copyright 2000, 2002, 2003, 2004 Free Software Foundation, Inc. 398944Sobrien Contributed by Cygnus Solutions (a Red Hat company). 498944Sobrien 598944Sobrien This file is part of GDB. 698944Sobrien 798944Sobrien This program is free software; you can redistribute it and/or modify 898944Sobrien it under the terms of the GNU General Public License as published by 998944Sobrien the Free Software Foundation; either version 2 of the License, or 1098944Sobrien (at your option) any later version. 1198944Sobrien 1298944Sobrien This program is distributed in the hope that it will be useful, 1398944Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1498944Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1598944Sobrien GNU General Public License for more details. 1698944Sobrien 1798944Sobrien You should have received a copy of the GNU General Public License 1898944Sobrien along with this program; if not, write to the Free Software 1998944Sobrien Foundation, Inc., 59 Temple Place - Suite 330, 2098944Sobrien Boston, MA 02111-1307, USA. */ 2198944Sobrien 2298944Sobrien#include "defs.h" 2398944Sobrien#include "target.h" 2498944Sobrien#include "frame.h" 2598944Sobrien#include "value.h" 2698944Sobrien#include "mi-cmds.h" 2798944Sobrien#include "ui-out.h" 2898944Sobrien#include "symtab.h" 29130803Smarcel#include "block.h" 30130803Smarcel#include "stack.h" 31130803Smarcel#include "dictionary.h" 32130803Smarcel#include "gdb_string.h" 3398944Sobrien 3498944Sobrienstatic void list_args_or_locals (int locals, int values, struct frame_info *fi); 3598944Sobrien 3698944Sobrien/* Print a list of the stack frames. Args can be none, in which case 3798944Sobrien we want to print the whole backtrace, or a pair of numbers 3898944Sobrien specifying the frame numbers at which to start and stop the 3998944Sobrien display. If the two numbers are equal, a single frame will be 4098944Sobrien displayed. */ 4198944Sobrienenum mi_cmd_result 4298944Sobrienmi_cmd_stack_list_frames (char *command, char **argv, int argc) 4398944Sobrien{ 4498944Sobrien int frame_low; 4598944Sobrien int frame_high; 4698944Sobrien int i; 47130803Smarcel struct cleanup *cleanup_stack; 4898944Sobrien struct frame_info *fi; 4998944Sobrien 5098944Sobrien if (!target_has_stack) 5198944Sobrien error ("mi_cmd_stack_list_frames: No stack."); 5298944Sobrien 5398944Sobrien if (argc > 2 || argc == 1) 5498944Sobrien error ("mi_cmd_stack_list_frames: Usage: [FRAME_LOW FRAME_HIGH]"); 5598944Sobrien 5698944Sobrien if (argc == 2) 5798944Sobrien { 5898944Sobrien frame_low = atoi (argv[0]); 5998944Sobrien frame_high = atoi (argv[1]); 6098944Sobrien } 6198944Sobrien else 6298944Sobrien { 6398944Sobrien /* Called with no arguments, it means we want the whole 6498944Sobrien backtrace. */ 6598944Sobrien frame_low = -1; 6698944Sobrien frame_high = -1; 6798944Sobrien } 6898944Sobrien 6998944Sobrien /* Let's position fi on the frame at which to start the 7098944Sobrien display. Could be the innermost frame if the whole stack needs 7198944Sobrien displaying, or if frame_low is 0. */ 7298944Sobrien for (i = 0, fi = get_current_frame (); 7398944Sobrien fi && i < frame_low; 7498944Sobrien i++, fi = get_prev_frame (fi)); 7598944Sobrien 7698944Sobrien if (fi == NULL) 7798944Sobrien error ("mi_cmd_stack_list_frames: Not enough frames in stack."); 7898944Sobrien 79130803Smarcel cleanup_stack = make_cleanup_ui_out_list_begin_end (uiout, "stack"); 8098944Sobrien 8198944Sobrien /* Now let;s print the frames up to frame_high, or until there are 8298944Sobrien frames in the stack. */ 8398944Sobrien for (; 8498944Sobrien fi && (i <= frame_high || frame_high == -1); 8598944Sobrien i++, fi = get_prev_frame (fi)) 8698944Sobrien { 8798944Sobrien QUIT; 8898944Sobrien /* level == i: always print the level 'i' 8998944Sobrien source == LOC_AND_ADDRESS: print the location and the address 9098944Sobrien always, even for level 0. 9198944Sobrien args == 0: don't print the arguments. */ 9298944Sobrien print_frame_info (fi /* frame info */ , 9398944Sobrien i /* level */ , 9498944Sobrien LOC_AND_ADDRESS /* source */ , 9598944Sobrien 0 /* args */ ); 9698944Sobrien } 9798944Sobrien 98130803Smarcel do_cleanups (cleanup_stack); 9998944Sobrien if (i < frame_high) 10098944Sobrien error ("mi_cmd_stack_list_frames: Not enough frames in stack."); 10198944Sobrien 10298944Sobrien return MI_CMD_DONE; 10398944Sobrien} 10498944Sobrien 10598944Sobrienenum mi_cmd_result 10698944Sobrienmi_cmd_stack_info_depth (char *command, char **argv, int argc) 10798944Sobrien{ 10898944Sobrien int frame_high; 10998944Sobrien int i; 11098944Sobrien struct frame_info *fi; 11198944Sobrien 11298944Sobrien if (!target_has_stack) 11398944Sobrien error ("mi_cmd_stack_info_depth: No stack."); 11498944Sobrien 11598944Sobrien if (argc > 1) 11698944Sobrien error ("mi_cmd_stack_info_depth: Usage: [MAX_DEPTH]"); 11798944Sobrien 11898944Sobrien if (argc == 1) 11998944Sobrien frame_high = atoi (argv[0]); 12098944Sobrien else 12198944Sobrien /* Called with no arguments, it means we want the real depth of 12298944Sobrien the stack. */ 12398944Sobrien frame_high = -1; 12498944Sobrien 12598944Sobrien for (i = 0, fi = get_current_frame (); 12698944Sobrien fi && (i < frame_high || frame_high == -1); 12798944Sobrien i++, fi = get_prev_frame (fi)) 12898944Sobrien QUIT; 12998944Sobrien 13098944Sobrien ui_out_field_int (uiout, "depth", i); 13198944Sobrien 13298944Sobrien return MI_CMD_DONE; 13398944Sobrien} 13498944Sobrien 13598944Sobrien/* Print a list of the locals for the current frame. With argument of 13698944Sobrien 0, print only the names, with argument of 1 print also the 13798944Sobrien values. */ 13898944Sobrienenum mi_cmd_result 13998944Sobrienmi_cmd_stack_list_locals (char *command, char **argv, int argc) 14098944Sobrien{ 141130803Smarcel struct frame_info *frame; 142130803Smarcel enum print_values print_values; 143130803Smarcel 14498944Sobrien if (argc != 1) 14598944Sobrien error ("mi_cmd_stack_list_locals: Usage: PRINT_VALUES"); 14698944Sobrien 147130803Smarcel frame = get_selected_frame (); 148130803Smarcel 149130803Smarcel if (strcmp (argv[0], "0") == 0 150130803Smarcel || strcmp (argv[0], "--no-values") == 0) 151130803Smarcel print_values = PRINT_NO_VALUES; 152130803Smarcel else if (strcmp (argv[0], "1") == 0 153130803Smarcel || strcmp (argv[0], "--all-values") == 0) 154130803Smarcel print_values = PRINT_ALL_VALUES; 155130803Smarcel else if (strcmp (argv[0], "2") == 0 156130803Smarcel || strcmp (argv[0], "--simple-values") == 0) 157130803Smarcel print_values = PRINT_SIMPLE_VALUES; 158130803Smarcel else 159130803Smarcel error ("Unknown value for PRINT_VALUES: must be: 0 or \"--no-values\", 1 or \"--all-values\", 2 or \"--simple-values\""); 160130803Smarcel list_args_or_locals (1, print_values, frame); 16198944Sobrien return MI_CMD_DONE; 16298944Sobrien} 16398944Sobrien 16498944Sobrien/* Print a list of the arguments for the current frame. With argument 16598944Sobrien of 0, print only the names, with argument of 1 print also the 16698944Sobrien values. */ 16798944Sobrienenum mi_cmd_result 16898944Sobrienmi_cmd_stack_list_args (char *command, char **argv, int argc) 16998944Sobrien{ 17098944Sobrien int frame_low; 17198944Sobrien int frame_high; 17298944Sobrien int i; 17398944Sobrien struct frame_info *fi; 174130803Smarcel struct cleanup *cleanup_stack_args; 17598944Sobrien 17698944Sobrien if (argc < 1 || argc > 3 || argc == 2) 17798944Sobrien error ("mi_cmd_stack_list_args: Usage: PRINT_VALUES [FRAME_LOW FRAME_HIGH]"); 17898944Sobrien 17998944Sobrien if (argc == 3) 18098944Sobrien { 18198944Sobrien frame_low = atoi (argv[1]); 18298944Sobrien frame_high = atoi (argv[2]); 18398944Sobrien } 18498944Sobrien else 18598944Sobrien { 18698944Sobrien /* Called with no arguments, it means we want args for the whole 18798944Sobrien backtrace. */ 18898944Sobrien frame_low = -1; 18998944Sobrien frame_high = -1; 19098944Sobrien } 19198944Sobrien 19298944Sobrien /* Let's position fi on the frame at which to start the 19398944Sobrien display. Could be the innermost frame if the whole stack needs 19498944Sobrien displaying, or if frame_low is 0. */ 19598944Sobrien for (i = 0, fi = get_current_frame (); 19698944Sobrien fi && i < frame_low; 19798944Sobrien i++, fi = get_prev_frame (fi)); 19898944Sobrien 19998944Sobrien if (fi == NULL) 20098944Sobrien error ("mi_cmd_stack_list_args: Not enough frames in stack."); 20198944Sobrien 202130803Smarcel cleanup_stack_args = make_cleanup_ui_out_list_begin_end (uiout, "stack-args"); 20398944Sobrien 20498944Sobrien /* Now let's print the frames up to frame_high, or until there are 20598944Sobrien frames in the stack. */ 20698944Sobrien for (; 20798944Sobrien fi && (i <= frame_high || frame_high == -1); 20898944Sobrien i++, fi = get_prev_frame (fi)) 20998944Sobrien { 210130803Smarcel struct cleanup *cleanup_frame; 21198944Sobrien QUIT; 212130803Smarcel cleanup_frame = make_cleanup_ui_out_tuple_begin_end (uiout, "frame"); 21398944Sobrien ui_out_field_int (uiout, "level", i); 21498944Sobrien list_args_or_locals (0, atoi (argv[0]), fi); 215130803Smarcel do_cleanups (cleanup_frame); 21698944Sobrien } 21798944Sobrien 218130803Smarcel do_cleanups (cleanup_stack_args); 21998944Sobrien if (i < frame_high) 22098944Sobrien error ("mi_cmd_stack_list_args: Not enough frames in stack."); 22198944Sobrien 22298944Sobrien return MI_CMD_DONE; 22398944Sobrien} 22498944Sobrien 22598944Sobrien/* Print a list of the locals or the arguments for the currently 22698944Sobrien selected frame. If the argument passed is 0, printonly the names 22798944Sobrien of the variables, if an argument of 1 is passed, print the values 22898944Sobrien as well. */ 22998944Sobrienstatic void 23098944Sobrienlist_args_or_locals (int locals, int values, struct frame_info *fi) 23198944Sobrien{ 23298944Sobrien struct block *block; 23398944Sobrien struct symbol *sym; 234130803Smarcel struct dict_iterator iter; 235130803Smarcel int nsyms; 236130803Smarcel struct cleanup *cleanup_list; 23798944Sobrien static struct ui_stream *stb = NULL; 238130803Smarcel struct type *type; 23998944Sobrien 24098944Sobrien stb = ui_out_stream_new (uiout); 24198944Sobrien 242130803Smarcel block = get_frame_block (fi, 0); 24398944Sobrien 244130803Smarcel cleanup_list = make_cleanup_ui_out_list_begin_end (uiout, locals ? "locals" : "args"); 24598944Sobrien 24698944Sobrien while (block != 0) 24798944Sobrien { 248130803Smarcel ALL_BLOCK_SYMBOLS (block, iter, sym) 24998944Sobrien { 25098944Sobrien int print_me = 0; 25198944Sobrien 25298944Sobrien switch (SYMBOL_CLASS (sym)) 25398944Sobrien { 25498944Sobrien default: 25598944Sobrien case LOC_UNDEF: /* catches errors */ 25698944Sobrien case LOC_CONST: /* constant */ 25798944Sobrien case LOC_TYPEDEF: /* local typedef */ 25898944Sobrien case LOC_LABEL: /* local label */ 25998944Sobrien case LOC_BLOCK: /* local function */ 26098944Sobrien case LOC_CONST_BYTES: /* loc. byte seq. */ 26198944Sobrien case LOC_UNRESOLVED: /* unresolved static */ 26298944Sobrien case LOC_OPTIMIZED_OUT: /* optimized out */ 26398944Sobrien print_me = 0; 26498944Sobrien break; 26598944Sobrien 26698944Sobrien case LOC_ARG: /* argument */ 26798944Sobrien case LOC_REF_ARG: /* reference arg */ 26898944Sobrien case LOC_REGPARM: /* register arg */ 26998944Sobrien case LOC_REGPARM_ADDR: /* indirect register arg */ 27098944Sobrien case LOC_LOCAL_ARG: /* stack arg */ 27198944Sobrien case LOC_BASEREG_ARG: /* basereg arg */ 272130803Smarcel case LOC_COMPUTED_ARG: /* arg with computed location */ 27398944Sobrien if (!locals) 27498944Sobrien print_me = 1; 27598944Sobrien break; 27698944Sobrien 27798944Sobrien case LOC_LOCAL: /* stack local */ 27898944Sobrien case LOC_BASEREG: /* basereg local */ 27998944Sobrien case LOC_STATIC: /* static */ 28098944Sobrien case LOC_REGISTER: /* register */ 281130803Smarcel case LOC_COMPUTED: /* computed location */ 28298944Sobrien if (locals) 28398944Sobrien print_me = 1; 28498944Sobrien break; 28598944Sobrien } 28698944Sobrien if (print_me) 28798944Sobrien { 288130803Smarcel struct cleanup *cleanup_tuple = NULL; 289130803Smarcel struct symbol *sym2; 290130803Smarcel if (values != PRINT_NO_VALUES) 291130803Smarcel cleanup_tuple = 292130803Smarcel make_cleanup_ui_out_tuple_begin_end (uiout, NULL); 293130803Smarcel ui_out_field_string (uiout, "name", SYMBOL_PRINT_NAME (sym)); 29498944Sobrien 295130803Smarcel if (!locals) 296130803Smarcel sym2 = lookup_symbol (SYMBOL_NATURAL_NAME (sym), 297130803Smarcel block, VAR_DOMAIN, 298130803Smarcel (int *) NULL, 299130803Smarcel (struct symtab **) NULL); 300130803Smarcel else 301130803Smarcel sym2 = sym; 302130803Smarcel switch (values) 30398944Sobrien { 304130803Smarcel case PRINT_SIMPLE_VALUES: 305130803Smarcel type = check_typedef (sym2->type); 306130803Smarcel type_print (sym2->type, "", stb->stream, -1); 307130803Smarcel ui_out_field_stream (uiout, "type", stb); 308130803Smarcel if (TYPE_CODE (type) != TYPE_CODE_ARRAY 309130803Smarcel && TYPE_CODE (type) != TYPE_CODE_STRUCT 310130803Smarcel && TYPE_CODE (type) != TYPE_CODE_UNION) 311130803Smarcel { 312130803Smarcel print_variable_value (sym2, fi, stb->stream); 313130803Smarcel ui_out_field_stream (uiout, "value", stb); 314130803Smarcel } 315130803Smarcel do_cleanups (cleanup_tuple); 316130803Smarcel break; 317130803Smarcel case PRINT_ALL_VALUES: 31898944Sobrien print_variable_value (sym2, fi, stb->stream); 31998944Sobrien ui_out_field_stream (uiout, "value", stb); 320130803Smarcel do_cleanups (cleanup_tuple); 321130803Smarcel break; 32298944Sobrien } 32398944Sobrien } 32498944Sobrien } 32598944Sobrien if (BLOCK_FUNCTION (block)) 32698944Sobrien break; 32798944Sobrien else 32898944Sobrien block = BLOCK_SUPERBLOCK (block); 32998944Sobrien } 330130803Smarcel do_cleanups (cleanup_list); 33198944Sobrien ui_out_stream_delete (stb); 33298944Sobrien} 33398944Sobrien 33498944Sobrienenum mi_cmd_result 33598944Sobrienmi_cmd_stack_select_frame (char *command, char **argv, int argc) 33698944Sobrien{ 33798944Sobrien if (!target_has_stack) 33898944Sobrien error ("mi_cmd_stack_select_frame: No stack."); 33998944Sobrien 34098944Sobrien if (argc > 1) 34198944Sobrien error ("mi_cmd_stack_select_frame: Usage: [FRAME_SPEC]"); 34298944Sobrien 34398944Sobrien /* with no args, don't change frame */ 34498944Sobrien if (argc == 0) 345130803Smarcel select_frame_command (0, 1 /* not used */ ); 34698944Sobrien else 347130803Smarcel select_frame_command (argv[0], 1 /* not used */ ); 34898944Sobrien return MI_CMD_DONE; 34998944Sobrien} 350