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]

[unwind-20030108-branch] Make certain that the duplicated PC's arein sync


Hello,

Some cleanups:

- make certain that the PC(s) is always in sync. Once `struct frame_info' is made opaque, the redundency can be removed.

- to keep things simple, have sentinel frame's next loop back on itself.

Andrew
2003-01-11  Andrew Cagney  <ac131313@redhat.com>

	* frame.c (deprecated_update_frame_pc_hack)
	(deprecated_update_frame_base_hack): Also update the next frame's
	ID/PC cache.
	(create_sentinel_frame): Link the sentinel frame to itself.
	* frame.h: Expand comments describing update PC and FP hacks.
	* frame.c (get_prev_frame): Add comment explaining why
	INIT_EXTRA_FRAME_INFO call is needed.
	(legacy_get_prev_frame): Use get_next_frame.
	
Index: frame.c
===================================================================
RCS file: /cvs/src/src/gdb/frame.c,v
retrieving revision 1.56.2.2
diff -u -r1.56.2.2 frame.c
--- frame.c	10 Jan 2003 21:56:43 -0000	1.56.2.2
+++ frame.c	11 Jan 2003 21:15:31 -0000
@@ -57,6 +57,29 @@
     }
 }
 
+struct frame_id
+frame_id_unwind (struct frame_info *frame)
+{
+  if (!frame->id_unwind_cache_p)
+    {
+      frame->id_unwind (frame, &frame->unwind_cache, &frame->id_unwind_cache);
+      frame->id_unwind_cache_p = 1;
+    }
+  return frame->id_unwind_cache;
+}
+
+void
+deprecated_update_frame_base_hack (struct frame_info *frame, CORE_ADDR base)
+{
+  /* See comment in "frame.h".  */
+  frame->frame = base;
+  gdb_assert (frame->next != NULL);
+  gdb_assert (frame->next->id_unwind_cache_p);
+  gdb_assert (frame->next->pc_unwind_cache_p);
+  frame->next->id_unwind_cache.base = base;
+  frame->next->id_unwind_cache.pc = frame->next->pc_unwind_cache;
+}
+
 const struct frame_id null_frame_id; /* All zeros.  */
 
 struct frame_id
@@ -125,28 +148,6 @@
   return NULL;
 }
 
-CORE_ADDR
-frame_pc_unwind (struct frame_info *frame)
-{
-  if (!frame->pc_unwind_cache_p)
-    {
-      frame->pc_unwind_cache = frame->pc_unwind (frame, &frame->unwind_cache);
-      frame->pc_unwind_cache_p = 1;
-    }
-  return frame->pc_unwind_cache;
-}
-
-struct frame_id
-frame_id_unwind (struct frame_info *frame)
-{
-  if (!frame->id_unwind_cache_p)
-    {
-      frame->id_unwind (frame, &frame->unwind_cache, &frame->id_unwind_cache);
-      frame->id_unwind_cache_p = 1;
-    }
-  return frame->id_unwind_cache;
-}
-
 
 void
 frame_register_unwind (struct frame_info *frame, int regnum,
@@ -411,6 +412,10 @@
   frame->pc_unwind = sentinel_frame_pc_unwind;
   frame->id_unwind = sentinel_frame_id_unwind;
   frame->register_unwind = sentinel_frame_register_unwind;
+  /* Link this frame back to itself.  The frame is self referential
+     (the unwound PC is the same as the pc for instance, so make it
+     so.  */
+  frame->next = frame;
   /* Always unwind the PC as part of creating this frame.  This
      ensures that the frame's PC points into something valid.  */
   /* FIXME: cagney/2003-01-10: Problem here.  Unwinding a sentinel
@@ -686,6 +691,9 @@
   struct frame_info *prev;
   int fromleaf;
 
+  /* This code doesn't work with the sentinal frame.  */
+  gdb_assert (next_frame->level >= 0);
+
   /* On some machines it is possible to call a function without
      setting up a stack frame for it.  On these machines, we
      define this macro to take two args; a frameinfo pointer
@@ -695,7 +703,7 @@
   /* Still don't want to worry about this except on the innermost
      frame.  This macro will set FROMLEAF if NEXT_FRAME is a frameless
      function invocation.  */
-  if (next_frame->next == NULL)
+  if (get_next_frame (next_frame) == NULL)
     /* FIXME: 2002-11-09: Frameless functions can occure anywhere in
        the frame chain, not just the inner most frame!  The generic,
        per-architecture, frame code should handle this and the below
@@ -906,7 +914,15 @@
      NOTE: cagney/2003-01-10: Talk about code behaving badly.  Check
      block_innermost_frame().  It does the sequence: frame = NULL;
      while (1) { frame = get_prev_frame (frame); .... }.  Ulgh!  Why
-     it couldn't be written better, I don't know.  */
+     it couldn't be written better, I don't know.
+
+     NOTE: cagney/2003-01-11: I suspect what is happening is
+     block_innermost_frame() is, when the target has no state
+     (registers, memory, ...), still calling this function.  The
+     assumption being that this function will return NULL indicating
+     that a frame isn't possible, rather than checking that the target
+     has state and then calling get_current_frame() and
+     get_prev_frame().  This is a guess mind.  */
   if (next_frame == NULL)
     {
       /* NOTE: cagney/2002-11-09: There was a code segment here that
@@ -957,7 +973,7 @@
   if ((DEPRECATED_INIT_FRAME_PC_P ()
        || DEPRECATED_INIT_FRAME_PC_FIRST_P ())
       && next_frame->level >= 0)
-    /* Don't try to unwind the sentinal frame using the old code.  */
+     /* Don't try to unwind the sentinal frame using the old code.  */
     return legacy_get_prev_frame (next_frame);
 
   /* Allocate the new frame but do not wire it in.  Some (bad) code in
@@ -1024,6 +1040,8 @@
      Instead of initializing extra info, all frames will use the
      frame_cache (passed to the unwind functions) to store extra frame
      info.  */
+  /* NOTE: cagney/2003-01-11: Legacy targets, when having the sentinel
+     frame unwound, rely on this call.  */
   if (INIT_EXTRA_FRAME_INFO_P ())
     /* NOTE: This code doesn't bother trying to sort out frameless
        functions.  That is left to the target.  */
@@ -1035,9 +1053,39 @@
 CORE_ADDR
 get_frame_pc (struct frame_info *frame)
 {
+  /* This should just call frame_pc_unwind().  */
   return frame->pc;
 }
 
+CORE_ADDR
+frame_pc_unwind (struct frame_info *frame)
+{
+  if (!frame->pc_unwind_cache_p)
+    {
+      frame->pc_unwind_cache = frame->pc_unwind (frame, &frame->unwind_cache);
+      frame->pc_unwind_cache_p = 1;
+    }
+  return frame->pc_unwind_cache;
+}
+
+void
+deprecated_update_frame_pc_hack (struct frame_info *frame, CORE_ADDR pc)
+{
+  /* See comment in "frame.h".  */
+  frame->pc = pc;
+  gdb_assert (frame->next != NULL);
+  /* Got a bucket?  Legacy code that handles dummy frames directly
+     doesn't always use the unwind function to determine the dummy
+     frame's PC.  Consequently, it is possible for this function to be
+     called when the next frame's pc unwind cache isn't valid.  */
+  if (frame->next->pc_unwind_cache_p)
+    frame->next->pc_unwind_cache = pc;
+  /* Since the PC is unwound before the frame ID, only need to update
+     the frame ID's PC when it has been unwound.  */
+  if (frame->next->id_unwind_cache_p)
+    frame->next->id_unwind_cache.pc = pc;
+}
+
 static int
 pc_notcurrent (struct frame_info *frame)
 {
@@ -1138,20 +1186,6 @@
 {
   fi->extra_info = frame_obstack_zalloc (size);
   return fi->extra_info;
-}
-
-void
-deprecated_update_frame_pc_hack (struct frame_info *frame, CORE_ADDR pc)
-{
-  /* See comment in "frame.h".  */
-  frame->pc = pc;
-}
-
-void
-deprecated_update_frame_base_hack (struct frame_info *frame, CORE_ADDR base)
-{
-  /* See comment in "frame.h".  */
-  frame->frame = base;
 }
 
 void
Index: frame.h
===================================================================
RCS file: /cvs/src/src/gdb/frame.h,v
retrieving revision 1.59.2.1
diff -u -r1.59.2.1 frame.h
--- frame.h	10 Jan 2003 15:22:39 -0000	1.59.2.1
+++ frame.h	11 Jan 2003 21:16:37 -0000
@@ -663,17 +663,22 @@
 extern CORE_ADDR *frame_saved_regs_zalloc (struct frame_info *);
 extern CORE_ADDR *get_frame_saved_regs (struct frame_info *);
 
-/* FIXME: cagney/2002-12-06: Has the PC in the current frame changed?
-   "infrun.c", Thanks to DECR_PC_AFTER_BREAK, can change the PC after
-   the initial frame create.  This puts things back in sync.  */
+/* FIXME: cagney/2003-01-11: Fix up this frame's frame ID / PC (which
+   is cached in the next frame).  The problem here is with read_fp()/
+   FRAME_CHAIN() and read_pc() / FRAME_SAVED_PC.  Legacy code, instead
+   of returning the correct frame base from the word go, returns a
+   draft frame base and then fixes it up in INIT_FRAME_PC,
+   INIT_FRAME_PC_FIRST or INIT_EXTRA_FRAME_INFO.  Back patch the next
+   frame's frame ID so that it will now return the correct id.
+
+   For the PC, the problems are caused by DECR_PC_AFTER_BREAK and
+   DECR_PC_AFTER_HW_BREAK.
+
+   For the FP, the problems are caused by GDB requesting the FP
+   instead of the SP and, as a consequence, code trying to avoid the
+   overhead of unnecessary prologue analysis.  */
 extern void deprecated_update_frame_pc_hack (struct frame_info *frame,
 					     CORE_ADDR pc);
-
-/* FIXME: cagney/2002-12-18: Has the frame's base changed?  Or to be
-   more exact, whas that initial guess at the frame's base as returned
-   by read_fp() wrong.  If it was, fix it.  This shouldn't be
-   necessary since the code should be getting the frame's base correct
-   from the outset.  */
 extern void deprecated_update_frame_base_hack (struct frame_info *frame,
 					       CORE_ADDR base);
 

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