aboutsummaryrefslogtreecommitdiff
path: root/gdb/blockframe.c
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2003-01-05 01:39:56 +0000
committerDaniel Jacobowitz <drow@false.org>2003-01-05 01:39:56 +0000
commit516034834f1bcade05e3dcd85e9c7c8b899adbd6 (patch)
tree7dfa0fc3ff5a3e7da16a50ff725fac9a561d7ec8 /gdb/blockframe.c
parent95f90d2595724210a3f27456baeb6eed02ece2bc (diff)
downloadgdb-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.c133
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);
+}