* stack.c (select_frame): Check that selected_frame and the
authorAndrew Cagney <cagney@redhat.com>
Wed, 10 Apr 2002 22:14:02 +0000 (22:14 +0000)
committerAndrew Cagney <cagney@redhat.com>
Wed, 10 Apr 2002 22:14:02 +0000 (22:14 +0000)
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.

gdb/ChangeLog
gdb/blockframe.c
gdb/frame.h
gdb/stack.c

index a216d7d..39a50f3 100644 (file)
@@ -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.
index 8626ede..49bda4a 100644 (file)
@@ -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
index 5f952c5..a989890 100644 (file)
@@ -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
index bedb6ee..a348934 100644 (file)
@@ -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);