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]

[cagney_lazyid-20030317-branch] Try lazy frame ID evaluation


Hello,

I've created the branch cagney_lazyid-20030317-branch and comitted the attached. It implements the proposal to evaluate the frame's ID in a lazy fashion. Don't know if it works yet ...

I'm going to also try out the WFI changes (replace pc_in_call_dummy and pc_in_sigtramp, with get_frame_type (get_current_frame()) to see if the theory is matched by reality.

Andrew
2003-03-17  Andrew Cagney  <cagney at redhat dot com>

	* frame.c (get_frame_id): If the frame's ID isn't valid, get it.
	(get_prev_frame): Validate THIS frame's ID before trying to unwind
	to prev frame.  Don't compute PREV's frame's ID.
	(get_frame_base): Force the update of frame ID before returning
	the frame.
	* frame.h (struct frame_info): Add "id_p".

Index: frame.c
===================================================================
RCS file: /cvs/src/src/gdb/frame.c,v
retrieving revision 1.87
diff -u -r1.87 frame.c
--- frame.c	17 Mar 2003 14:23:49 -0000	1.87
+++ frame.c	17 Mar 2003 15:12:10 -0000
@@ -53,17 +53,50 @@
 struct frame_id
 get_frame_id (struct frame_info *fi)
 {
+  struct frame_id id;
   if (fi == NULL)
     {
+      /* Should never happen!  */
       return null_frame_id;
     }
-  else
+  if (!fi->id_p)
     {
-      struct frame_id id;
-      id.base = fi->frame;
-      id.pc = fi->pc;
-      return id;
+      gdb_assert (!legacy_frame_p (current_gdbarch));
+
+      /* Find THIS frame's ID.  */
+      fi->unwind->this_id (fi->next, &fi->prologue_cache, &fi->id);
+      fi->id_p = 1;
+
+      /* Check that the unwound ID is valid.  */
+      if (!frame_id_p (fi->id) && frame_debug)
+	fprintf_unfiltered (gdb_stdlog,
+			    "Unwound frame ID invalid\n");
+
+      /* 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 (fi->level >= 0 && frame_id_p (fi->id) && fi->next->id_p
+	  && frame_id_inner (fi->id, get_frame_id (fi->next)))
+	error ("Unwound frame inner-to selected frame (corrupt stack?)");
+
+      /* 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.  */
+
+      /* FIXME: cagney/2002-12-18: Instead of this hack, should only
+	 store the frame ID in PREV_FRAME.  Unfortunatly, some
+	 architectures (HP/UX) still reply on EXTRA_FRAME_INFO and,
+	 hence, still poke at the "struct frame_info" object directly.  */
+      fi->frame = fi->id.base;
     }
+  id.base = fi->frame;
+  id.pc = fi->pc;
+  return id;
 }
 
 const struct frame_id null_frame_id; /* All zeros.  */
@@ -1452,6 +1485,39 @@
       return NULL;
     }
 
+  /* If THIS frame ended up with a NULL frame ID, don't bother trying
+     to unwind it.  */
+  if (this_frame->level >= 0 && !frame_id_p (get_frame_id (this_frame)))
+    {
+      if (frame_debug)
+ 	fprintf_filtered (gdb_stdlog,
+ 			  "Outermost frame - next ID is NULL\n");
+      return NULL;
+    }
+
+  /* Check that THIS frame isn't inner to (younger, below, next) the
+     NEXT frame.  If that happens the frame unwind went backwards.  */
+  /* FIXME: cagney/2003-02-25: Instead of ignoring the sentinel frame
+     (since that doesn't have a valid frame ID), the code should 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 (get_frame_id (this_frame),
+			 get_frame_id (this_frame->next)))
+    error ("This frame inner-to next frame (corrupt stack?)");
+
+  /* Check that THIS and NEXT frame are different.  If they are not,
+     there is most likely a stack cycle.  */
+  /* FIXME: cagney/2003-03-17: Can't yet do this check. The
+     frame_id_eq() method doesn't yet use function addresses when
+     comparing 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?)");
+
   /* If any of the old frame initialization methods are around, use
      the legacy get_prev_frame method.  */
   if (legacy_frame_p (current_gdbarch))
@@ -1509,63 +1575,7 @@
   prev_frame->unwind = frame_unwind_find_by_pc (current_gdbarch,
 						prev_frame->pc);
 
-  /* Find the prev's frame's ID.  */
-
-  /* The callee expects to be invoked with:
-
-     this->unwind->this_id (this->next, &this->cache, &this->id);
-
-     The below is carefully shifted one frame `to the left' so that
-     both the unwind->this_id and unwind->prev_register methods are
-     consistently invoked with NEXT_FRAME and THIS_PROLOGUE_CACHE.
-       
-     Also note that, while the PC for this new previous frame was
-     unwound first (see above), the below is the first call that
-     [potentially] requires analysis of the new previous frame's
-     prologue.  Consequently, it is this call, that typically ends up
-     initializing the previous frame's prologue cache.  */
-  prev_frame->unwind->this_id (this_frame,
-			       &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.  */
-
-  /* FIXME: cagney/2002-12-18: Instead of this hack, should only store
-     the frame ID in PREV_FRAME.  Unfortunatly, some architectures
-     (HP/UX) still reply on EXTRA_FRAME_INFO and, hence, still poke at
-     the "struct frame_info" object directly.  */
-  prev_frame->frame = prev_frame->id.base;
+  /* The PREV's frame ID is computed on-demand in get_frame_id().  */
 
   /* Link it in.  */
   this_frame->prev = prev_frame;
@@ -1608,6 +1618,12 @@
 CORE_ADDR
 get_frame_base (struct frame_info *fi)
 {
+  if (!fi->id_p)
+    {
+      /* Force the ID code to (indirectly) initialize the ->frame
+         pointer.  */
+      get_frame_id (fi);
+    }
   return fi->frame;
 }
 
Index: frame.h
===================================================================
RCS file: /cvs/src/src/gdb/frame.h,v
retrieving revision 1.75
diff -u -r1.75 frame.h
--- frame.h	17 Mar 2003 14:23:49 -0000	1.75
+++ frame.h	17 Mar 2003 15:12:11 -0000
@@ -410,8 +410,10 @@
     CORE_ADDR pc_unwind_cache;
 
     /* This frame's ID.  Note that the frame's ID, base and PC contain
-       redundant information.  */
+       redundant information.  If id_p is non-zero, the ID is assumed
+       to be valid.  */
     struct frame_id id;
+    int id_p;
 
     /* Pointers to the next (down, inner, younger) and previous (up,
        outer, older) frame_info's in the frame cache.  */

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