This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[patch/rfc] Unwind the PC first when creating a frame
- From: Andrew Cagney <ac131313 at redhat dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Tue, 10 Dec 2002 21:42:47 -0500
- Subject: [patch/rfc] Unwind the PC first when creating a frame
Hello,
This patch changes the frame creation code so that it can unwind the PC
before doing anything else. By unwinding the PC first, it becomes
possible to correctly set the frame from the outset. The old code would
set the frame's type last (resulting in architecture code having to back
patch it). It also (at least in theory) makes it possible to avoid
certain frame unwinds.
Since, right now, all architectures currently specify a deprecated init
frame pc method, the code isn't used by any architecture. A follow on
will be to enable the code on at least one architecture.
I'll commit the attached in a few days,
enjoy,
Andrew
2002-12-10 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.40
diff -u -r1.40 frame.c
--- frame.c 11 Dec 2002 02:26:35 -0000 1.40
+++ frame.c 11 Dec 2002 02:33:57 -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
@@ -1080,12 +1117,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