aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog10
-rw-r--r--gdb/blockframe.c11
-rw-r--r--gdb/frame.h16
-rw-r--r--gdb/stack.c32
4 files changed, 63 insertions, 6 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index a216d7d..39a50f3 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,15 @@
2002-04-10 Andrew Cagney <ac131313@redhat.com>
+ * stack.c (select_frame): Check that selected_frame and the
+ specified level are as expected.
+ * blockframe.c (get_prev_frame): Set the `level' from next_frame.
+ Update copyright.
+ * frame.h (struct frame_info): Add field `level'. Update
+ copyright.
+ Work-in-progress PR gdb/464.
+
+2002-04-10 Andrew Cagney <ac131313@redhat.com>
+
* maint.c (maint_print_section_info): Rename print_section_info.
(print_bfd_section_info, print_objfile_section_info): Update.
* inferior.h (struct gdbarch): Add opaque declaration.
diff --git a/gdb/blockframe.c b/gdb/blockframe.c
index 8626ede..49bda4a 100644
--- a/gdb/blockframe.c
+++ b/gdb/blockframe.c
@@ -1,7 +1,9 @@
-/* Get info from stack frames;
- convert between frames, blocks, functions and pc values.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
- 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+/* Get info from stack frames; convert between frames, blocks,
+ functions and pc values.
+
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software
+ Foundation, Inc.
This file is part of GDB.
@@ -393,6 +395,7 @@ get_prev_frame (struct frame_info *next_frame)
next_frame->prev = prev;
prev->next = next_frame;
prev->frame = address;
+ prev->level = next_frame->level + 1;
/* This change should not be needed, FIXME! We should
determine whether any targets *need* INIT_FRAME_PC to happen
diff --git a/gdb/frame.h b/gdb/frame.h
index 5f952c5..a989890 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -1,6 +1,7 @@
/* Definitions for dealing with stack frames, for GDB, the GNU debugger.
- Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997,
- 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+ Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996,
+ 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of GDB.
@@ -63,6 +64,17 @@ struct frame_info
For other frames, it is a pc saved in the next frame. */
CORE_ADDR pc;
+ /* Level of this frame. The inner-most (youngest) frame is at
+ level 0. As you move towards the outer-most (oldest) frame,
+ the level increases. This is a cached value. It could just as
+ easily be computed by counting back from the selected frame to
+ the inner most frame. */
+ /* NOTE: cagney/2002-04-05: Perhaphs a level of ``-1'' should be
+ reserved to indicate a bogus frame - one that has been created
+ just to keep GDB happy (GDB always needs a frame). For the
+ moment leave this as speculation. */
+ int level;
+
/* Nonzero if this is a frame associated with calling a signal handler.
Set by machine-dependent code. On some machines, if
diff --git a/gdb/stack.c b/gdb/stack.c
index bedb6ee..a348934 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1458,6 +1458,38 @@ select_frame (struct frame_info *fi, int level)
selected_frame = fi;
selected_frame_level = level;
+ /* FIXME: cagney/2002-04-05: It can't be this easy (and looking at
+ the increasingly complex list of checkes, it wasn't)! GDB is
+ dragging around, and constantly updating, the global variable
+ selected_frame_level. Surely all that was needed was for the
+ level to be computed direct from the frame (by counting back to
+ the inner-most frame) or, as has been done here using a cached
+ value. For moment, check that the expected and the actual level
+ are consistent. If, after a few weeks, no one reports that this
+ assertion has failed, the global selected_frame_level and many
+ many parameters can all be deleted. */
+ if (fi == NULL && level == -1)
+ /* Ok. The target is clearing the selected frame as part of a
+ cache flush. */
+ ;
+ else if (fi != NULL && fi->level == level)
+ /* Ok. What you would expect. Level is redundant. */
+ ;
+ else if (fi != NULL && level == -1)
+ /* Ok. See breakpoint.c. The watchpoint code changes the
+ selected frame to the frame that contains the watchpoint and
+ then, later changes it back to the old value. The -1 is used
+ as a marker so that the watchpoint code can easily detect that
+ things are not what they should be. Why the watchpoint code
+ can't mindlessly save/restore the selected frame I don't know,
+ hopefully it can be simplified that way. Hopefully the global
+ selected_frame can be replaced by a frame parameter, making
+ still more simplification possible. */
+ ;
+ else
+ internal_error (__FILE__, __LINE__,
+ "oops! fi=0x%p, fi->level=%d, level=%d",
+ fi, fi ? fi->level : -1, level);
if (selected_frame_level_changed_hook)
selected_frame_level_changed_hook (level);