This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[wip] Unwind PC first
- From: Andrew Cagney <ac131313 at redhat dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Thu, 05 Dec 2002 12:14:10 -0500
- Subject: [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