This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[commit] Allow inspection of a bad frame


Hello,

See:  Lazy get_frame_id()
http://sources.redhat.com/ml/gdb/2003-03/msg00240.html

This patch delays the verification of a frame's ID until a further unwind is requested. By doing this, it becomes possible to `step onto' a bad frame, and hence examine things like its registers. Previously, GDB would refuse to go near such a frame, making examination impossible :-(

+  /* The unwound frame ID is validate at the start of this function,
+     as part of the logic to decide if that frame should be further
+     unwound, and not here while the prev frame is being created.
+     Doing this makes it possible for the user to examine a frame that
+     has an invalid frame ID.
+
+     The very old VAX frame_args_address_correct() method noted: [...]
+     For the sake of argument, suppose that the stack is somewhat
+     trashed (which is one reason that "info frame" exists).  So,
+     return 0 (indicating we don't know the address of the arglist) if
+     we don't know what frame this frame calls.  */

This change only applies to the new unwinders, and hence, can only affect the d10v.

It does not implement the lazy ID and infrun.c changes also mentioned in that post.

committed,
Andrew
2003-03-25  Andrew Cagney  <cagney at redhat dot com>

	* frame.c (get_prev_frame): Delay validating a frame's ID -
	non-NULL, didn't go backwards - until an attempt to unwind it to
	the previous frame.

Index: frame.c
===================================================================
RCS file: /cvs/src/src/gdb/frame.c,v
retrieving revision 1.88
diff -u -r1.88 frame.c
--- frame.c	24 Mar 2003 03:54:47 -0000	1.88
+++ frame.c	25 Mar 2003 23:58:39 -0000
@@ -1467,6 +1467,38 @@
       return prev_frame;
     }
 
+  /* Check that this frame's ID was valid.  If it wasn't, don't try to
+     unwind to the prev frame.  Be careful to not apply this test to
+     the sentinel frame.  */
+  if (this_frame->level >= 0 && !frame_id_p (get_frame_id (this_frame)))
+    {
+      if (frame_debug)
+ 	fprintf_filtered (gdb_stdlog,
+ 			  "Outermost frame - this ID is NULL\n");
+      return NULL;
+    }
+
+  /* Check that this frame's ID isn't inner to (younger, below, next)
+     the next frame.  This happens when frame unwind goes backwards.
+     Since the sentinel frame isn't valid, don't apply this if this
+     frame is entier the inner-most or sentinel frame.  */
+  if (this_frame->level > 0
+      && frame_id_inner (get_frame_id (this_frame),
+			 get_frame_id (this_frame->next)))
+    error ("This frame inner-to next frame (corrupt stack?)");
+
+  /* Check that this and the next frame are different.  If they are
+     not, there is most likely a stack cycle.  As with the inner-than
+     test, avoid the inner-most and sentinel frames.  */
+  /* FIXME: cagney/2003-03-17: Can't yet enable this this check. The
+     frame_id_eq() method doesn't yet use function addresses when
+     comparing frame IDs.  */
+  if (0
+      && this_frame->level > 0
+      && frame_id_eq (get_frame_id (this_frame),
+		      get_frame_id (this_frame->next)))
+    error ("This frame identical to next frame (corrupt stack?)");
+
   /* Allocate the new frame but do not wire it in to the frame chain.
      Some (bad) code in INIT_FRAME_EXTRA_INFO tries to look along
      frame->next to pull some fancy tricks (of course such code is, by
@@ -1533,38 +1565,17 @@
 			       &prev_frame->prologue_cache,
 			       &prev_frame->id);
 
-  /* Check that the unwound ID is valid.  */
-  if (!frame_id_p (prev_frame->id))
-    {
-      if (frame_debug)
-	fprintf_unfiltered (gdb_stdlog,
-			    "Outermost frame - unwound frame ID invalid\n");
-      return NULL;
-    }
-
-  /* Check that the new frame isn't inner to (younger, below, next)
-     the old frame.  If that happens the frame unwind is going
-     backwards.  */
-  /* FIXME: cagney/2003-02-25: Ignore the sentinel frame since that
-     doesn't have a valid frame ID.  Should instead set the sentinel
-     frame's frame ID to a true `sentinel'.  Leave it until after the
-     switch to storing the frame ID, instead of the frame base, in the
-     frame object.  */
-  if (this_frame->level >= 0
-      && frame_id_inner (prev_frame->id, get_frame_id (this_frame)))
-    error ("Unwound frame inner-to selected frame (corrupt stack?)");
-
-  /* FIXME: cagney/2003-03-14: Should check that this and next frame's
-     IDs are different (i.e., !frame_id_eq()).  Can't yet do that as
-     the EQ function doesn't yet compare PC values.  */
-
-  /* FIXME: cagney/2003-03-14: Should delay the evaluation of the
-     frame ID until when it is needed.  That way the inner most frame
-     can be created without needing to do prologue analysis.  */
-
-  /* Note that, due to frameless functions, the stronger test of the
-     new frame being outer to the old frame can't be used - frameless
-     functions differ by only their PC value.  */
+  /* The unwound frame ID is validate at the start of this function,
+     as part of the logic to decide if that frame should be further
+     unwound, and not here while the prev frame is being created.
+     Doing this makes it possible for the user to examine a frame that
+     has an invalid frame ID.
+
+     The very old VAX frame_args_address_correct() method noted: [...]
+     For the sake of argument, suppose that the stack is somewhat
+     trashed (which is one reason that "info frame" exists).  So,
+     return 0 (indicating we don't know the address of the arglist) if
+     we don't know what frame this frame calls.  */
 
   /* FIXME: cagney/2002-12-18: Instead of this hack, should only store
      the frame ID in PREV_FRAME.  Unfortunatly, some architectures

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]