diff options
author | Daniel Jacobowitz <drow@false.org> | 2003-01-05 01:39:56 +0000 |
---|---|---|
committer | Daniel Jacobowitz <drow@false.org> | 2003-01-05 01:39:56 +0000 |
commit | 516034834f1bcade05e3dcd85e9c7c8b899adbd6 (patch) | |
tree | 7dfa0fc3ff5a3e7da16a50ff725fac9a561d7ec8 /gdb/blockframe.c | |
parent | 95f90d2595724210a3f27456baeb6eed02ece2bc (diff) | |
download | gdb-516034834f1bcade05e3dcd85e9c7c8b899adbd6.zip gdb-516034834f1bcade05e3dcd85e9c7c8b899adbd6.tar.gz gdb-516034834f1bcade05e3dcd85e9c7c8b899adbd6.tar.bz2 |
* arm-tdep.c (arm_frame_chain_valid): Remove unnecessary test.
* d10v-tdep.c (d10v_frame_chain_valid): Remove unnecessary tests.
* hppa-tdep.c (hppa_frame_chain_valid): Remove unnecessary test.
* blockframe.c: Include "gdbcmd.h" and "command.h".
(backtrace_below_main): New variable.
(file_frame_chain_valid, func_frame_chain_valid)
(nonnull_frame_chain_valid, generic_file_frame_chain_valid)
(generic_func_frame_chain_valid): Remove functions.
(frame_chain_valid, do_flush_frames_sfunc): New functions.
(_initialize_blockframe): New function.
* Makefile.in (blockframe.o): Update dependencies.
* frame.c (frame_saved_regs_id_unwind, get_prev_frame): Remove FIXME
comment. Call frame_chain_valid ().
* frame.h: Remove old prototypes. Add prototype for
frame_chain_valid and update comments to match.
* gdbarch.sh: Change FRAME_CHAIN_VALID into a predicated function.
Remove old comment.
* gdbarch.h: Regenerated.
* gdbarch.c: Regenerated.
Plus updates to all other targets not to provide a FRAME_CHAIN_VALID.
Diffstat (limited to 'gdb/blockframe.c')
-rw-r--r-- | gdb/blockframe.c | 133 |
1 files changed, 80 insertions, 53 deletions
diff --git a/gdb/blockframe.c b/gdb/blockframe.c index 665b1ba..35fc798 100644 --- a/gdb/blockframe.c +++ b/gdb/blockframe.c @@ -2,7 +2,7 @@ functions and pc values. Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, - 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GDB. @@ -36,41 +36,16 @@ #include "regcache.h" #include "gdb_assert.h" #include "dummy-frame.h" +#include "command.h" +#include "gdbcmd.h" -/* Prototypes for exported functions. */ - -void _initialize_blockframe (void); +/* Flag to indicate whether backtraces should stop at main. */ -/* A default FRAME_CHAIN_VALID, in the form that is suitable for most - targets. If FRAME_CHAIN_VALID returns zero it means that the given - frame is the outermost one and has no caller. */ - -int -file_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe) -{ - return ((chain) != 0 - && !inside_entry_file (frame_pc_unwind (thisframe))); -} - -/* Use the alternate method of avoiding running up off the end of the - frame chain or following frames back into the startup code. See - the comments in objfiles.h. */ - -int -func_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe) -{ - return ((chain) != 0 - && !inside_main_func (get_frame_pc (thisframe)) - && !inside_entry_func (get_frame_pc (thisframe))); -} +static int backtrace_below_main; -/* A very simple method of determining a valid frame */ +/* Prototypes for exported functions. */ -int -nonnull_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe) -{ - return ((chain) != 0); -} +void _initialize_blockframe (void); /* Is ADDR inside the startup file? Note that if your machine has a way to detect the bottom of the stack, there is no need @@ -689,34 +664,86 @@ deprecated_pc_in_call_dummy_at_entry_point (CORE_ADDR pc, CORE_ADDR sp, && (pc) <= (CALL_DUMMY_ADDRESS () + DECR_PC_AFTER_BREAK)); } - /* Function: frame_chain_valid Returns true for a user frame or a call_function_by_hand dummy frame, - and false for the CRT0 start-up frame. Purpose is to terminate backtrace */ + and false for the CRT0 start-up frame. Purpose is to terminate backtrace. */ int -generic_file_frame_chain_valid (CORE_ADDR fp, struct frame_info *fi) +frame_chain_valid (CORE_ADDR fp, struct frame_info *fi) { - if (DEPRECATED_PC_IN_CALL_DUMMY (frame_pc_unwind (fi), fp, fp)) - return 1; /* don't prune CALL_DUMMY frames */ - else /* fall back to default algorithm (see frame.h) */ - return (fp != 0 - && (INNER_THAN (get_frame_base (fi), fp) - || get_frame_base (fi) == fp) - && !inside_entry_file (frame_pc_unwind (fi))); + /* Don't prune CALL_DUMMY frames. */ + if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES + && DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), 0, 0)) + return 1; + + /* If the new frame pointer is zero, then it isn't valid. */ + if (fp == 0) + return 0; + + /* If the new frame would be inside (younger than) the previous frame, + then it isn't valid. */ + if (INNER_THAN (fp, get_frame_base (fi))) + return 0; + + /* If we're already inside the entry function for the main objfile, then it + isn't valid. */ + if (inside_entry_func (get_frame_pc (fi))) + return 0; + + /* If we're inside the entry file, it isn't valid. */ + /* NOTE/drow 2002-12-25: should there be a way to disable this check? It + assumes a single small entry file, and the way some debug readers (e.g. + dbxread) figure out which object is the entry file is somewhat hokey. */ + if (inside_entry_file (frame_pc_unwind (fi))) + return 0; + + /* If we want backtraces to stop at main, and we're inside main, then it + isn't valid. */ + if (!backtrace_below_main && inside_main_func (get_frame_pc (fi))) + return 0; + + /* If the architecture has a custom FRAME_CHAIN_VALID, call it now. */ + if (FRAME_CHAIN_VALID_P ()) + return FRAME_CHAIN_VALID (fp, fi); + + return 1; } -int -generic_func_frame_chain_valid (CORE_ADDR fp, struct frame_info *fi) +void +do_flush_frames_sfunc (char *args, int from_tty, struct cmd_list_element *c) { - if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES - && DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), 0, 0)) - return 1; /* don't prune CALL_DUMMY frames */ - else /* fall back to default algorithm (see frame.h) */ - return (fp != 0 - && (INNER_THAN (get_frame_base (fi), fp) - || get_frame_base (fi) == fp) - && !inside_main_func (get_frame_pc (fi)) - && !inside_entry_func (get_frame_pc (fi))); + int saved_level; + struct frame_info *cur_frame; + + if (! target_has_stack) + return; + + saved_level = frame_relative_level (get_selected_frame ()); + + flush_cached_frames (); + + cur_frame = find_relative_frame (get_current_frame (), &saved_level); + select_frame (cur_frame); + + /* If we were below main and backtrace-below-main was turned off, + SAVED_LEVEL will be non-zero. CUR_FRAME will point to main. + Accept this but print the new frame. */ + if (saved_level != 0) + print_stack_frame (get_selected_frame (), -1, 0); } +void +_initialize_blockframe (void) +{ + add_setshow_boolean_cmd ("backtrace-below-main", class_obscure, + &backtrace_below_main, + "Set whether backtraces should continue past \"main\".\n" + "Normally the caller of \"main\" is not of interest, so GDB will terminate\n" + "the backtrace at \"main\". Set this variable if you need to see the rest\n" + "of the stack trace.", + "Show whether backtraces should continue past \"main\".\n" + "Normally the caller of \"main\" is not of interest, so GDB will terminate\n" + "the backtrace at \"main\". Set this variable if you need to see the rest\n" + "of the stack trace.", + do_flush_frames_sfunc, NULL, &setlist, &showlist); +} |