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]

[wip] Unwind PC first


Hello,

The attached follows up the post:
[still looking]

It illustrates exactly how I'm planning implementing the change of unwinding the PC before doing anything else related to creating a new frame.

I tried adding the code un-conditionally. Unfortunatly, while the i386 worked ok, the rs6000 a few extra failures. Consequently, I'm going to make the unwind call conditional on having neither INIT_FRAME_PC nor INIT_FRAME_PC_FIRST.

The rollout will be interesting. I'm expecting three phases:

- convert INIT_FRAME_PC and INIT_FRAME_PC_FIRST into deprecated functions with predicates (as was done to PC_IN_CALL_DUMMY) (two separate patches).

- apply the attached

- eliminate any definitions of the now deprecated INIT_FRAME_PC and INIT_FRAME_PC_FIRST.


comments,
Andrew

(PS: There is also another un-related patch to INIT_FRAME_PC and INIT_FRAME_PC_FIRST that changes those procedures into true functions. It's part of the ongoing war against code pokeing directly at the `struct frame_info' internals.)
2002-12-05  Andrew Cagney  <ac131313@redhat.com>

	* frame.c (frame_type_from_pc): New function.
	(create_new_frame): Use frame_type_from_pc instead of custom code.
	(get_prev_frame): When neither DEPRECATED_INIT_FRAME_PC_P nor
	DEPRECATED_INIT_FRAME_PC_FIRST_P use frame_type_from_pc and
	frame_pc_unwind to set the frame's type at the point of frame
	creation.

Index: frame.c
===================================================================
RCS file: /cvs/src/src/gdb/frame.c,v
retrieving revision 1.37
diff -u -r1.37 frame.c
--- frame.c	4 Dec 2002 00:05:53 -0000	1.37
+++ frame.c	5 Dec 2002 16:44:09 -0000
@@ -767,6 +767,29 @@
     }
 }
 
+/* Determine the frame's type based on its PC.  */
+
+static enum frame_type
+frame_type_from_pc (CORE_ADDR pc)
+{
+  /* FIXME: cagney/2002-11-24: Can't yet directly call
+     pc_in_dummy_frame() as some architectures don't set
+     PC_IN_CALL_DUMMY() to generic_pc_in_call_dummy() (remember the
+     latter is implemented by simply calling pc_in_dummy_frame).  */
+  if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES
+      && PC_IN_CALL_DUMMY (pc, 0, 0))
+    return DUMMY_FRAME;
+  else
+    {
+      char *name;
+      find_pc_partial_function (pc, &name, NULL, NULL);
+      if (PC_IN_SIGTRAMP (pc, name))
+	return SIGTRAMP_FRAME;
+      else
+	return NORMAL_FRAME;
+    }
+}
+
 /* Create an arbitrary (i.e. address specified by user) or innermost frame.
    Always returns a non-NULL value.  */
 
@@ -785,30 +808,7 @@
 
   fi->frame = addr;
   fi->pc = pc;
-  /* NOTE: cagney/2002-11-18: The code segments, found in
-     create_new_frame and get_prev_frame(), that initializes the
-     frames type is subtly different.  The latter only updates ->type
-     when it encounters a SIGTRAMP_FRAME or DUMMY_FRAME.  This stops
-     get_prev_frame() overriding the frame's type when the INIT code
-     has previously set it.  This is really somewhat bogus.  The
-     initialization, as seen in create_new_frame(), should occur
-     before the INIT function has been called.  */
-  if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES
-      && (DEPRECATED_PC_IN_CALL_DUMMY_P ()
-	  ? DEPRECATED_PC_IN_CALL_DUMMY (pc, 0, 0)
-	  : pc_in_dummy_frame (pc)))
-    /* NOTE: cagney/2002-11-11: Does this even occure?  */
-    type = DUMMY_FRAME;
-  else
-    {
-      char *name;
-      find_pc_partial_function (pc, &name, NULL, NULL);
-      if (PC_IN_SIGTRAMP (fi->pc, name))
-	type = SIGTRAMP_FRAME;
-      else
-	type = NORMAL_FRAME;
-    }
-  fi->type = type;
+  fi->type = frame_type_from_pc (pc);
 
   if (INIT_EXTRA_FRAME_INFO_P ())
     INIT_EXTRA_FRAME_INFO (0, fi);
@@ -867,6 +867,8 @@
   CORE_ADDR address = 0;
   struct frame_info *prev;
   int fromleaf;
+  CORE_ADDR pc;
+  enum frame_type type;
 
   /* Return the inner-most frame, when the caller passes in NULL.  */
   /* NOTE: cagney/2002-11-09: Not sure how this would happen.  The
@@ -895,6 +897,41 @@
     return next_frame->prev;
   next_frame->prev_p = 1;
 
+  /* Try to unwind the PC.  If that doesn't work, assume we've reached
+     the oldest frame and simply return.  Is there a better sentinal
+     value?  The unwound PC value is then used to initialize the new
+     previous frame's type.
+
+     Note that the pc-unwind is intentionally performed before the
+     frame chain.  This is (well should be ok) since, for old targets,
+     both frame_pc_unwind (nee, FRAME_SAVED_PC) and FRAME_CHAIN())
+     assume NEXT_FRAME's data structures have already been initialized
+     (using INIT_EXTRA_FRAME_INFO) and hence the call order doesn't
+     matter.
+
+     By unwinding the PC first, it becomes possible to, in the case of
+     a dummy frame, avoid also unwinding the frame ID.  This is
+     because (well ignoring the PPC) a dummy frame can be located
+     using NEXT_FRAME's frame ID.
+
+     For the moment this is only done conditionally.  Some targets
+     (e.g., rs6000) appear to break when this change is enabled.  */
+  if (DEPRECATED_INIT_FRAME_PC_P ()
+      || DEPRECATED_INIT_FRAME_PC_FIRST_P ())
+    {
+      /* Ulgh, old style target that still uses one of the
+         INIT_FRAME_PC methods.  */
+      pc = 0;
+      type = 0;
+    }
+  else
+    {
+      pc = frame_pc_unwind (next_frame);
+      if (pc == 0)
+	return NULL;
+      type = frame_type_from_pc (pc);
+    }
+
   /* 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
@@ -1077,12 +1114,15 @@
      has previously set it.  This is really somewhat bogus.  The
      initialization, as seen in create_new_frame(), should occur
      before the INIT function has been called.  */
-  if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES
+  if ((DEPRECATED_INIT_FRAME_PC_P ()
+       || DEPRECATED_INIT_FRAME_PC_FIRST_P ())
+      && DEPRECATED_USE_GENERIC_DUMMY_FRAMES
       && (DEPRECATED_PC_IN_CALL_DUMMY_P ()
 	  ? DEPRECATED_PC_IN_CALL_DUMMY (prev->pc, 0, 0)
 	  : pc_in_dummy_frame (prev->pc)))
     prev->type = DUMMY_FRAME;
-  else
+  else if (DEPRECATED_INIT_FRAME_PC_P ()
+	   || DEPRECATED_INIT_FRAME_PC_FIRST_P ())
     {
       /* FIXME: cagney/2002-11-10: This should be moved to before the
 	 INIT code above so that the INIT code knows what the frame's

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