diff options
Diffstat (limited to 'gdb/RCS/stack.c,v')
-rw-r--r-- | gdb/RCS/stack.c,v | 882 |
1 files changed, 0 insertions, 882 deletions
diff --git a/gdb/RCS/stack.c,v b/gdb/RCS/stack.c,v deleted file mode 100644 index fc755c2..0000000 --- a/gdb/RCS/stack.c,v +++ /dev/null @@ -1,882 +0,0 @@ -head 1.2; -access ; -symbols ; -locks ; strict; -comment @ * @; - - -1.2 -date 89.02.09.23.53.05; author gnu; state Exp; -branches ; -next 1.1; - -1.1 -date 89.02.09.15.03.51; author gnu; state Exp; -branches ; -next ; - - -desc -@@ - - -1.2 -log -@Avoid coredumps if stack commands are used when there is no stack. -@ -text -@/* Print and select stack frames for GDB, the GNU debugger. - Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc. - -GDB is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY. No author or distributor accepts responsibility to anyone -for the consequences of using it or for whether it serves any -particular purpose or works at all, unless he says so in writing. -Refer to the GDB General Public License for full details. - -Everyone is granted permission to copy, modify and redistribute GDB, -but only under the conditions described in the GDB General Public -License. A copy of this license is supposed to have been given to you -along with GDB so you can know your rights and responsibilities. It -should be in a file named COPYING. Among other things, the copyright -notice and this notice must be preserved on all copies. - -In other words, go ahead and share GDB, but don't try to stop -anyone else from sharing it farther. Help stamp out software hoarding! -*/ - -#include <stdio.h> - -#include "defs.h" -#include "param.h" -#include "symtab.h" -#include "frame.h" -#include "inferior.h" -#include "gdbcore.h" - - -/* Thie "selected" stack frame is used by default for local and arg access. - May be zero, for no selected frame. */ - -FRAME selected_frame; - -/* Level of the selected frame: - 0 for innermost, 1 for its caller, ... - or -1 for frame specified by address with no defined level. */ - -int selected_frame_level; - -/* Error message when selected_frame is zero when it's needed */ -char no_sel_frame[] = "There is no current stack frame."; - -/* Nonzero means print the full filename and linenumber - when a frame is printed, and do so in a format programs can parse. */ - -int frame_file_full_name = 0; - -static void select_calling_frame (); - -void print_frame_info (); - -/* Print a stack frame briefly. FRAME should be the frame address - and LEVEL should be its level in the stack (or -1 for level not defined). - This prints the level, the function executing, the arguments, - and the file name and line number. - If the pc is not at the beginning of the source line, - the actual pc is printed at the beginning. - - If SOURCE is 1, print the source line as well. - If SOURCE is -1, print ONLY the source line. */ - -/* FIXME, the argument "frame" is always "selected_frame". This is why - we can say "No selected frame" if it == 0. Probably shouldn't be an - argument anymore... */ - -static void -print_stack_frame (frame, level, source) - FRAME frame; - int level; - int source; -{ - struct frame_info *fi; - - if (frame == 0) - error (no_sel_frame); - fi = get_frame_info (frame); - - print_frame_info (fi, level, source, 1); -} - -void -print_frame_info (fi, level, source, args) - struct frame_info *fi; - register int level; - int source; - int args; -{ - struct symtab_and_line sal; - struct symbol *func; - register char *funname = 0; - int numargs; - - sal = find_pc_line (fi->pc, fi->next_frame); - func = find_pc_function (fi->pc); - if (func) - funname = SYMBOL_NAME (func); - else - { - register int misc_index = find_pc_misc_function (fi->pc); - if (misc_index >= 0) - funname = misc_function_vector[misc_index].name; - } - - if (source >= 0 || !sal.symtab) - { - if (level >= 0) - printf ("#%-2d ", level); - if (fi->pc != sal.pc || !sal.symtab) - printf ("0x%x in ", fi->pc); - printf ("%s (", funname ? funname : "??"); - if (args) - { - FRAME_NUM_ARGS (numargs, fi); - print_frame_args (func, fi, numargs, stdout); - } - printf (")"); - if (sal.symtab) - printf (" (%s line %d)", sal.symtab->filename, sal.line); - printf ("\n"); - } - - if (source != 0 && sal.symtab) - { - int done = 0; - int mid_statement = source < 0 && fi->pc != sal.pc; - if (frame_file_full_name) - done = identify_source_line (sal.symtab, sal.line, mid_statement); - if (!done) - { - if (mid_statement) - printf ("0x%x\t", fi->pc); - print_source_lines (sal.symtab, sal.line, sal.line + 1, 1); - } - current_source_line = max (sal.line - 5, 1); - } - if (source != 0) - set_default_breakpoint (1, fi->pc, sal.symtab, sal.line); - - fflush (stdout); -} - -/* Call here to print info on selected frame, after a trap. */ - -void -print_sel_frame (just_source) - int just_source; -{ - print_stack_frame (selected_frame, -1, just_source ? -1 : 1); -} - -/* Print info on the selected frame, including level number - but not source. */ - -void -print_selected_frame () -{ - print_stack_frame (selected_frame, selected_frame_level, 0); -} - -void flush_cached_frames (); /* FIXME, never called! */ - -#ifdef FRAME_SPECIFICATION_DYADIC -extern FRAME setup_arbitrary_frame (); -#endif - -/* - * Read a frame specification in whatever the appropriate format is. - */ -static FRAME -parse_frame_specification (frame_exp) - char *frame_exp; -{ - int numargs = 0; - int arg1, arg2; - - if (frame_exp) - { - char *addr_string, *p; - struct cleanup *tmp_cleanup; - struct frame_info *fci; - - while (*frame_exp == ' ') frame_exp++; - for (p = frame_exp; *p && *p != ' '; p++) - ; - - if (*frame_exp) - { - numargs = 1; - addr_string = savestring(frame_exp, p - frame_exp); - - { - tmp_cleanup = make_cleanup (free, addr_string); - arg1 = parse_and_eval_address (addr_string); - do_cleanups (tmp_cleanup); - } - - while (*p == ' ') p++; - - if (*p) - { - numargs = 2; - arg2 = parse_and_eval_address (p); - } - } - } - - switch (numargs) - { - case 0: - if (selected_frame == 0) - error (no_sel_frame); - return selected_frame; - /* NOTREACHED */ - case 1: - { - int level = arg1; - FRAME fid = find_relative_frame (get_current_frame (), &level); - FRAME tfid; - - if (level == 0) - /* find_relative_frame was successful */ - return fid; - - /* If (s)he specifies the frame with an address, he deserves what - (s)he gets. Still, give the highest one that matches. */ - - for (fid = get_current_frame (); - fid && FRAME_FP (fid) != arg1; - fid = get_prev_frame (fid)) - ; - - if (fid) - while ((tfid = get_prev_frame (fid)) && - (FRAME_FP (tfid) == arg1)) - fid = tfid; - -#ifdef FRAME_SPECIFICATION_DYADIC - if (!fid) - error ("Incorrect number of args in frame specification"); - - return fid; -#else - return create_new_frame (arg1, 0); -#endif - } - /* NOTREACHED */ - case 2: - /* Must be addresses */ -#ifndef FRAME_SPECIFICATION_DYADIC - error ("Incorrect number of args in frame specification"); -#else - return setup_arbitrary_frame (arg1, arg2); -#endif - /* NOTREACHED */ - } - fatal ("Internal: Error in parsing in parse_frame_specification"); - /* NOTREACHED */ -} - -/* Print verbosely the selected frame or the frame at address ADDR. - This means absolutely all information in the frame is printed. */ - -static void -frame_info (addr_exp) - char *addr_exp; -{ - FRAME frame; - struct frame_info *fi; - struct frame_saved_regs fsr; - struct symtab_and_line sal; - struct symbol *func; - FRAME calling_frame; - int i, count; - char *funname = 0; - int numargs; - - frame = parse_frame_specification (addr_exp); - - fi = get_frame_info (frame); - get_frame_saved_regs (fi, &fsr); - sal = find_pc_line (fi->pc, fi->next_frame); - func = get_frame_function (frame); - if (func) - funname = SYMBOL_NAME (func); - else - { - register int misc_index = find_pc_misc_function (fi->pc); - if (misc_index >= 0) - funname = misc_function_vector[misc_index].name; - } - calling_frame = get_prev_frame (frame); - - if (!addr_exp && selected_frame_level >= 0) - printf ("Stack level %d, frame at 0x%x:\n pc = 0x%x", - selected_frame_level, FRAME_FP(frame), fi->pc); - else - printf ("Stack frame at 0x%x:\n pc = 0x%x", - FRAME_FP(frame), fi->pc); - - if (funname) - printf (" in %s", funname); - if (sal.symtab) - printf (" (%s line %d)", sal.symtab->filename, sal.line); - printf ("; saved pc 0x%x\n", FRAME_SAVED_PC (frame)); - if (calling_frame) - printf (" called by frame at 0x%x", FRAME_FP (calling_frame)); - if (fi->next_frame && calling_frame) - printf (","); - if (fi->next_frame) - printf (" caller of frame at 0x%x", fi->next_frame); - if (fi->next_frame || calling_frame) - printf ("\n"); - printf (" Arglist at 0x%x,", FRAME_ARGS_ADDRESS (fi)); - FRAME_NUM_ARGS (i, fi); - if (i < 0) - printf (" args: "); - else if (i == 0) - printf (" no args."); - else if (i == 1) - printf (" 1 arg: "); - else - printf (" %d args: ", i); - - FRAME_NUM_ARGS (numargs, fi); - print_frame_args (func, fi, numargs, stdout); - printf ("\n"); - count = 0; - for (i = 0; i < NUM_REGS; i++) - if (fsr.regs[i]) - { - if (count % 4 != 0) - printf (", "); - else - { - if (count == 0) - printf (" Saved registers:"); - printf ("\n "); - } - printf ("%s at 0x%x", reg_names[i], fsr.regs[i]); - count++; - } - if (count) - printf ("\n"); -} - -#if 0 -/* Set a limit on the number of frames printed by default in a - backtrace. */ - -static int backtrace_limit; - -static void -set_backtrace_limit_command (count_exp, from_tty) - char *count_exp; - int from_tty; -{ - int count = parse_and_eval_address (count_exp); - - if (count < 0) - error ("Negative argument not meaningful as backtrace limit."); - - backtrace_limit = count; -} - -static void -backtrace_limit_info (arg, from_tty) - char *arg; - int from_tty; -{ - if (arg) - error ("\"Info backtrace-limit\" takes no arguments."); - - printf ("Backtrace limit: %d.\n", backtrace_limit); -} -#endif - -/* Print briefly all stack frames or just the innermost COUNT frames. */ - -static void -backtrace_command (count_exp) - char *count_exp; -{ - struct frame_info *fi; - register int count; - register FRAME frame; - register int i; - register FRAME trailing; - register int trailing_level; - - if (have_inferior_p () == 0 && corefile == 0) - error ("There is no running program or core file."); - - /* The following code must do two things. First, it must - set the variable TRAILING to the frame from which we should start - printing. Second, it must set the variable count to the number - of frames which we should print, or -1 if all of them. */ - trailing = get_current_frame (); - trailing_level = 0; - if (count_exp) - { - count = parse_and_eval_address (count_exp); - if (count < 0) - { - FRAME current; - - count = -count; - - current = trailing; - while (current && count--) - current = get_prev_frame (current); - - /* Will stop when CURRENT reaches the top of the stack. TRAILING - will be COUNT below it. */ - while (current) - { - trailing = get_prev_frame (trailing); - current = get_prev_frame (current); - trailing_level++; - } - - count = -1; - } - } - else -#if 0 - count = backtrace_limit; -#else - count = -1; -#endif - - for (i = 0, frame = trailing; - frame && count--; - i++, frame = get_prev_frame (frame)) - { - QUIT; - fi = get_frame_info (frame); - print_frame_info (fi, trailing_level + i, 0, 1); - } - - /* If we've stopped before the end, mention that. */ - if (frame) - printf ("(More stack frames follow...)\n"); -} - -/* Print the local variables of a block B active in FRAME. */ - -static void -print_block_frame_locals (b, frame, stream) - struct block *b; - register FRAME frame; - register FILE *stream; -{ - int nsyms; - register int i; - register struct symbol *sym; - - nsyms = BLOCK_NSYMS (b); - - for (i = 0; i < nsyms; i++) - { - sym = BLOCK_SYM (b, i); - if (SYMBOL_CLASS (sym) == LOC_LOCAL - || SYMBOL_CLASS (sym) == LOC_REGISTER - || SYMBOL_CLASS (sym) == LOC_STATIC) - { - fprintf (stream, "%s = ", SYMBOL_NAME (sym)); - print_variable_value (sym, frame, stream); - fprintf (stream, "\n"); - fflush (stream); - } - } -} - -/* Print on STREAM all the local variables in frame FRAME, - including all the blocks active in that frame - at its current pc. - - Returns 1 if the job was done, - or 0 if nothing was printed because we have no info - on the function running in FRAME. */ - -static int -print_frame_local_vars (frame, stream) - register FRAME frame; - register FILE *stream; -{ - register struct block *block; - - block = get_frame_block (frame); - if (block == 0) - return 0; - while (block != 0) - { - print_block_frame_locals (block, frame, stream); - /* After handling the function's top-level block, stop. - Don't continue to its superblock, the block of - per-file symbols. */ - if (BLOCK_FUNCTION (block)) - break; - block = BLOCK_SUPERBLOCK (block); - } - return 1; -} - -static void -locals_info () -{ - if (selected_frame == 0) - error(no_sel_frame); - print_frame_local_vars (selected_frame, stdout); -} - -static int -print_frame_arg_vars (frame, stream) - register FRAME frame; - register FILE *stream; -{ - struct symbol *func; - register struct block *b; - int nsyms; - register int i; - register struct symbol *sym; - - func = get_frame_function (frame); - if (func == 0) - return 0; - - b = SYMBOL_BLOCK_VALUE (func); - nsyms = BLOCK_NSYMS (b); - - for (i = 0; i < nsyms; i++) - { - sym = BLOCK_SYM (b, i); - if (SYMBOL_CLASS (sym) == LOC_ARG || SYMBOL_CLASS (sym) == LOC_REGPARM) - { - fprintf (stream, "%s = ", SYMBOL_NAME (sym)); - print_variable_value (sym, frame, stream); - fprintf (stream, "\n"); - fflush (stream); - } - } - - return 1; -} - -static void -args_info () -{ - if (selected_frame == 0) - error(no_sel_frame); - print_frame_arg_vars (selected_frame, stdout); -} - -/* Select frame FRAME, and note that its stack level is LEVEL. - LEVEL may be -1 if an actual level number is not known. */ - -void -select_frame (frame, level) - FRAME frame; - int level; -{ - selected_frame = frame; - selected_frame_level = level; -} - -/* Store the selected frame and its level into *FRAMEP and *LEVELP. */ - -void -record_selected_frame (frameaddrp, levelp) - FRAME_ADDR *frameaddrp; - int *levelp; -{ - *frameaddrp = FRAME_FP (selected_frame); - *levelp = selected_frame_level; -} - -/* Return the symbol-block in which the selected frame is executing. - Can return zero under various legitimate circumstances. */ - -struct block * -get_selected_block () -{ - if (!have_inferior_p () && !have_core_file_p ()) - return 0; - - if (!selected_frame) - return get_current_block (); - return get_frame_block (selected_frame); -} - -/* Find a frame a certain number of levels away from FRAME. - LEVEL_OFFSET_PTR points to an int containing the number of levels. - Positive means go to earlier frames (up); negative, the reverse. - The int that contains the number of levels is counted toward - zero as the frames for those levels are found. - If the top or bottom frame is reached, that frame is returned, - but the final value of *LEVEL_OFFSET_PTR is nonzero and indicates - how much farther the original request asked to go. */ - -FRAME -find_relative_frame (frame, level_offset_ptr) - register FRAME frame; - register int* level_offset_ptr; -{ - register FRAME prev; - register FRAME frame1, frame2; - - if (frame == 0) - error (no_sel_frame); - /* Going up is simple: just do get_prev_frame enough times - or until initial frame is reached. */ - while (*level_offset_ptr > 0) - { - prev = get_prev_frame (frame); - if (prev == 0) - break; - (*level_offset_ptr)--; - frame = prev; - } - /* Going down could be done by iterating get_frame_info to - find the next frame, but that would be quadratic - since get_frame_info must scan all the way from the current frame. - The following algorithm is linear. */ - if (*level_offset_ptr < 0) - { - /* First put frame1 at innermost frame - and frame2 N levels up from there. */ - frame1 = get_current_frame (); - frame2 = frame1; - while (*level_offset_ptr < 0 && frame2 != frame) - { - frame2 = get_prev_frame (frame2); - (*level_offset_ptr) ++; - } - /* Then slide frame1 and frame2 up in synchrony - and when frame2 reaches our starting point - frame1 must be N levels down from there. */ - while (frame2 != frame) - { - frame1 = get_prev_frame (frame1); - frame2 = get_prev_frame (frame2); - } - return frame1; - } - return frame; -} - -/* The "frame" command. With no arg, print selected frame briefly. - With arg LEVEL_EXP, select the frame at level LEVEL if it is a - valid level. Otherwise, treat level_exp as an address expression - and print it. See parse_frame_specification for more info on proper - frame expressions. */ - -static void -frame_command (level_exp, from_tty) - char *level_exp; - int from_tty; -{ - register FRAME frame, frame1; - unsigned int level = 0; - - frame = parse_frame_specification (level_exp); - - for (frame1 = get_prev_frame (0); - frame1 && frame1 != frame; - frame1 = get_prev_frame (frame1)) - level++; - - if (!frame1) - level = 0; - - select_frame (frame, level); - - if (!from_tty) - return; - - print_stack_frame (selected_frame, selected_frame_level, 1); -} - -/* Select the frame up one or COUNT stack levels - from the previously selected frame, and print it briefly. */ - -static void -up_command (count_exp) - char *count_exp; -{ - register FRAME frame; - int count = 1, count1; - if (count_exp) - count = parse_and_eval_address (count_exp); - count1 = count; - - frame = find_relative_frame (selected_frame, &count1); - if (count1 != 0 && count_exp == 0) - error ("Initial frame selected; you cannot go up."); - select_frame (frame, selected_frame_level + count - count1); - - print_stack_frame (selected_frame, selected_frame_level, 1); -} - -/* Select the frame down one or COUNT stack levels - from the previously selected frame, and print it briefly. */ - -static void -down_command (count_exp) - char *count_exp; -{ - register FRAME frame; - int count = -1, count1; - if (count_exp) - count = - parse_and_eval_address (count_exp); - count1 = count; - - frame = find_relative_frame (selected_frame, &count1); - if (count1 != 0 && count_exp == 0) - error ("Bottom (i.e., innermost) frame selected; you cannot go down."); - select_frame (frame, selected_frame_level + count - count1); - - print_stack_frame (selected_frame, selected_frame_level, 1); -} - -static void -return_command (retval_exp, from_tty) - char *retval_exp; - int from_tty; -{ - struct symbol *thisfun = get_frame_function (selected_frame); - - /* If interactive, require confirmation. */ - - if (from_tty) - { - if (thisfun != 0) - { - if (!query ("Make %s return now? ", SYMBOL_NAME (thisfun))) - error ("Not confirmed."); - } - else - if (!query ("Make selected stack frame return now? ")) - error ("Not confirmed."); - } - - /* Do the real work. Pop until the specified frame is current. */ - - while (selected_frame != get_current_frame ()) - POP_FRAME; - - /* Then pop that frame. */ - - POP_FRAME; - - /* Compute the return value (if any) and store in the place - for return values. */ - - if (retval_exp) - set_return_value (parse_and_eval (retval_exp)); - - /* If interactive, print the frame that is now current. */ - - if (from_tty) - frame_command ("0", 1); -} - -extern struct cmd_list_element *setlist; - -void -_initialize_stack () -{ -#if 0 - backtrace_limit = 30; -#endif - - add_com ("return", class_stack, return_command, - "Make selected stack frame return to its caller.\n\ -Control remains in the debugger, but when you continue\n\ -execution will resume in the frame above the one now selected.\n\ -If an argument is given, it is an expression for the value to return."); - - add_com ("up", class_stack, up_command, - "Select and print stack frame that called this one.\n\ -An argument says how many frames up to go."); - - add_com ("down", class_stack, down_command, - "Select and print stack frame called by this one.\n\ -An argument says how many frames down to go."); - add_com_alias ("do", "down", class_stack, 1); - - add_com ("frame", class_stack, frame_command, - "Select and print a stack frame.\n\ -With no argument, print the selected stack frame. (See also \"info frame\").\n\ -An argument specifies the frame to select.\n\ -It can be a stack frame number or the address of the frame.\n\ -With argument, nothing is printed if input is coming from\n\ -a command file or a user-defined command."); - - add_com_alias ("f", "frame", class_stack, 1); - - add_com ("backtrace", class_stack, backtrace_command, - "Print backtrace of all stack frames, or innermost COUNT frames.\n\ -With a negative argument, print outermost -COUNT frames."); - add_com_alias ("bt", "backtrace", class_stack, 0); - add_com_alias ("where", "backtrace", class_alias, 0); - add_info ("stack", backtrace_command, - "Backtrace of the stack, or innermost COUNT frames."); - add_info_alias ("s", "stack", 1); - add_info ("frame", frame_info, - "All about selected stack frame, or frame at ADDR."); - add_info_alias ("f", "frame", 1); - add_info ("locals", locals_info, - "Local variables of current stack frame."); - add_info ("args", args_info, - "Argument variables of current stack frame."); - -#if 0 - add_cmd ("backtrace-limit", class_stack, set_backtrace_limit_command, - "Specify maximum number of frames for \"backtrace\" to print by default.", - &setlist); - add_info ("backtrace-limit", backtrace_limit_info, - "The maximum number of frames for \"backtrace\" to print by default."); -#endif -} - -@ - - -1.1 -log -@Initial revision -@ -text -@d2 1 -a2 1 - Copyright (C) 1986, 1987 Free Software Foundation, Inc. -d27 2 -d42 3 -d64 4 -d76 2 -d162 1 -a162 1 -void flush_cached_frames (); -d212 2 -d392 3 -d489 3 -a491 1 - register struct block *block = get_frame_block (frame); -d510 2 -d520 1 -a520 1 - struct symbol *func = get_frame_function (frame); -d526 1 -d551 2 -d610 2 -@ |