This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[rfc] unwind_dummy_id
- From: Andrew Cagney <ac131313 at redhat dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Thu, 27 Feb 2003 16:03:50 -0500
- Subject: [rfc] unwind_dummy_id
http://sources.redhat.com/ml/gdb/2003-02/msg00549.html
This patch adds such a mechanism. I'm going to table this until someone
comes up with evidence that it actually fixes a bug :-)
Anyway. Eli, does the doco look ok? Once the evidence supporting this
is there, I'll commit it.
Andrew
2003-02-27 Andrew Cagney <cagney at redhat dot com>
* frame.c (get_prev_frame): Rewrite the frame ID unwind code to
use unwind_dummy_id when available.
* gdbarch.sh (get_dummy_frame_id): New multi-arch method with
predicate.
* gdbarch.h, gdbarch.c: Regneerate.
Index: doc/ChangeLog
2003-02-27 Andrew Cagney <cagney at redhat dot com>
* gdbint.texinfo (Target Architecture Definition): Document
unwind_dummy_id. Cross reference unwind_dummy_id and
SAVE_DUMMY_FRAME_TOS.
Index: frame.c
===================================================================
RCS file: /cvs/src/src/gdb/frame.c,v
retrieving revision 1.69
diff -u -r1.69 frame.c
--- frame.c 25 Feb 2003 23:52:16 -0000 1.69
+++ frame.c 27 Feb 2003 20:54:28 -0000
@@ -1338,37 +1338,70 @@
prev_frame->unwind = frame_unwind_find_by_pc (current_gdbarch,
prev_frame->pc);
- /* FIXME: cagney/2003-01-13: A dummy frame doesn't need to unwind
- the frame ID because the frame ID comes from the previous frame.
- The other frames do though. True? */
+ /* Find the prev's frame's ID. */
{
- /* FIXME: cagney/2002-12-18: Instead of this hack, should just
- save the frame ID directly. */
- struct frame_id id = frame_id_unwind (next_frame);
- /* Check that the unwound ID is valid. As of 2003-02-24 the
- x86-64 was returning an invalid frame ID when trying to do an
- unwind a sentinel frame that belonged to a frame dummy. */
- if (!frame_id_p (id))
+ struct frame_id id;
+ switch (prev_frame->type)
{
- if (frame_debug)
- fprintf_unfiltered (gdb_stdlog,
- "Outermost frame - unwound frame ID invalid\n");
- return NULL;
+ case DUMMY_FRAME:
+ /* A dummy doesn't have anything resembling either a sane
+ frame or PC. The PC is sitting in the entry code and the
+ stack, which has nothing to do with that entry address, is
+ a down right mess. Trying to use the standard frame ID
+ unwind code to get the previous frame ID is just asking for
+ trouble. */
+ if (gdbarch_unwind_dummy_id_p (current_gdbarch))
+ {
+ /* Assume hand_function_call(), via SAVE_DUMMY_FRAME_TOS,
+ previously saved the dummy ID that is being obtained
+ here. Things only work if the two match. */
+ gdb_assert (SAVE_DUMMY_FRAME_TOS_P ());
+ /* Use an architecture specific method to extract the
+ prev's dummy ID from the next frame. Note that this
+ method typically uses frame_register_unwind to obtain
+ register values needed to determine the dummy ID. */
+ id = gdbarch_unwind_dummy_id (current_gdbarch, next_frame);
+ }
+ else
+ {
+ /* Sigh! Try using the frame specific unwind method, but
+ be warned! It is likely to end in disaster. The main
+ reason this is here is to keep existing targets
+ (mostly) working. */
+ id = frame_id_unwind (next_frame);
+ }
+ break;
+ case NORMAL_FRAME:
+ case SIGTRAMP_FRAME:
+ id = frame_id_unwind (next_frame);
+ /* Check that the unwound ID is valid. */
+ if (!frame_id_p (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 `sentinel'. Leave it until
+ after the switch to storing the frame ID, instead of the
+ frame base, in the frame object. */
+ if (next_frame->level >= 0
+ && frame_id_inner (id, get_frame_id (next_frame)))
+ 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. */
+ break;
}
- /* 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 `sentinel'. Leave it until after the
- switch to storing the frame ID, instead of the frame base, in
- the frame object. */
- if (next_frame->level >= 0
- && frame_id_inner (id, get_frame_id (next_frame)))
- 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, the frame ID
+ should be directly stored in the `struct frame_info'.
+ Unfortunatly, GDB isn't quite ready for this, need to get HP/UX
+ multi-arch and make 'struct frame_info' opaque. */
prev_frame->frame = id.base;
}
Index: gdbarch.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.c,v
retrieving revision 1.182
diff -u -r1.182 gdbarch.c
--- gdbarch.c 27 Feb 2003 17:48:46 -0000 1.182
+++ gdbarch.c 27 Feb 2003 20:54:29 -0000
@@ -250,6 +250,7 @@
int extra_stack_alignment_needed;
gdbarch_reg_struct_has_addr_ftype *reg_struct_has_addr;
gdbarch_save_dummy_frame_tos_ftype *save_dummy_frame_tos;
+ gdbarch_unwind_dummy_id_ftype *unwind_dummy_id;
int parm_boundary;
const struct floatformat * float_format;
const struct floatformat * double_format;
@@ -429,6 +430,7 @@
0,
0,
0,
+ 0,
generic_in_function_epilogue_p,
construct_inferior_arguments,
0,
@@ -775,6 +777,7 @@
/* Skip verify of extra_stack_alignment_needed, invalid_p == 0 */
/* Skip verify of reg_struct_has_addr, has predicate */
/* Skip verify of save_dummy_frame_tos, has predicate */
+ /* Skip verify of unwind_dummy_id, has predicate */
if (gdbarch->float_format == 0)
gdbarch->float_format = default_float_format (gdbarch);
if (gdbarch->double_format == 0)
@@ -2537,6 +2540,14 @@
(long) current_gdbarch->write_sp
/*TARGET_WRITE_SP ()*/);
#endif
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: gdbarch_unwind_dummy_id_p() = %d\n",
+ gdbarch_unwind_dummy_id_p (current_gdbarch));
+ if (GDB_MULTI_ARCH)
+ fprintf_unfiltered (file,
+ "gdbarch_dump: unwind_dummy_id = 0x%08lx\n",
+ (long) current_gdbarch->unwind_dummy_id);
#ifdef USE_STRUCT_CONVENTION
fprintf_unfiltered (file,
"gdbarch_dump: %s # %s\n",
@@ -4958,6 +4969,32 @@
gdbarch_save_dummy_frame_tos_ftype save_dummy_frame_tos)
{
gdbarch->save_dummy_frame_tos = save_dummy_frame_tos;
+}
+
+int
+gdbarch_unwind_dummy_id_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->unwind_dummy_id != 0;
+}
+
+struct frame_id
+gdbarch_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *info)
+{
+ gdb_assert (gdbarch != NULL);
+ if (gdbarch->unwind_dummy_id == 0)
+ internal_error (__FILE__, __LINE__,
+ "gdbarch: gdbarch_unwind_dummy_id invalid");
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_unwind_dummy_id called\n");
+ return gdbarch->unwind_dummy_id (gdbarch, info);
+}
+
+void
+set_gdbarch_unwind_dummy_id (struct gdbarch *gdbarch,
+ gdbarch_unwind_dummy_id_ftype unwind_dummy_id)
+{
+ gdbarch->unwind_dummy_id = unwind_dummy_id;
}
int
Index: gdbarch.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.h,v
retrieving revision 1.143
diff -u -r1.143 gdbarch.h
--- gdbarch.h 27 Feb 2003 17:48:46 -0000 1.143
+++ gdbarch.h 27 Feb 2003 20:54:29 -0000
@@ -2352,6 +2352,12 @@
#endif
#endif
+extern int gdbarch_unwind_dummy_id_p (struct gdbarch *gdbarch);
+
+typedef struct frame_id (gdbarch_unwind_dummy_id_ftype) (struct gdbarch *gdbarch, struct frame_info *info);
+extern struct frame_id gdbarch_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *info);
+extern void set_gdbarch_unwind_dummy_id (struct gdbarch *gdbarch, gdbarch_unwind_dummy_id_ftype *unwind_dummy_id);
+
extern int gdbarch_parm_boundary (struct gdbarch *gdbarch);
extern void set_gdbarch_parm_boundary (struct gdbarch *gdbarch, int parm_boundary);
#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PARM_BOUNDARY)
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.195
diff -u -r1.195 gdbarch.sh
--- gdbarch.sh 27 Feb 2003 17:48:47 -0000 1.195
+++ gdbarch.sh 27 Feb 2003 20:54:31 -0000
@@ -581,6 +581,7 @@
v:2:EXTRA_STACK_ALIGNMENT_NEEDED:int:extra_stack_alignment_needed::::0:1::0:::
F:2:REG_STRUCT_HAS_ADDR:int:reg_struct_has_addr:int gcc_p, struct type *type:gcc_p, type::0:0
F:2:SAVE_DUMMY_FRAME_TOS:void:save_dummy_frame_tos:CORE_ADDR sp:sp::0:0
+M::UNWIND_DUMMY_ID:struct frame_id:unwind_dummy_id:struct frame_info *info:info::0:0
v:2:PARM_BOUNDARY:int:parm_boundary
#
v:2:TARGET_FLOAT_FORMAT:const struct floatformat *:float_format::::::default_float_format (gdbarch)::%s:(TARGET_FLOAT_FORMAT)->name
Index: doc/gdbint.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdbint.texinfo,v
retrieving revision 1.123
diff -u -r1.123 gdbint.texinfo
--- doc/gdbint.texinfo 4 Feb 2003 23:59:26 -0000 1.123
+++ doc/gdbint.texinfo 27 Feb 2003 20:54:35 -0000
@@ -3689,10 +3689,11 @@
@item SAVE_DUMMY_FRAME_TOS (@var{sp})
@findex SAVE_DUMMY_FRAME_TOS
-Used in @samp{call_function_by_hand} to notify the target dependent code
-of the top-of-stack value that will be passed to the the inferior code.
-This is the value of the @code{SP} after both the dummy frame and space
-for parameters/results have been allocated on the stack.
+ at anchor{SAVE_DUMMY_FRAME_TOS} Used in @samp{call_function_by_hand} to
+notify the target dependent code of the top-of-stack value that will be
+passed to the the inferior code. This is the value of the @code{SP}
+after both the dummy frame and space for parameters/results have been
+allocated on the stack. @xref{unwind_dummy_id}.
@item SDB_REG_TO_REGNUM
@findex SDB_REG_TO_REGNUM
@@ -3875,6 +3876,14 @@
Libraries, ,Opcodes}). @var{info} is a structure (of type
@code{disassemble_info}) defined in @file{include/dis-asm.h} used to
pass information to the instruction decoding routine.
+
+ at item struct frame_id unwind_dummy_id (struct frame_info * at var{frame})
+ at findex unwind_dummy_id
+ at anchor{unwind_dummy_id} Given @var{frame} return a @code{struct
+frame_id} that uniquely identifies an inferior function call's dummy
+frame. The value returned must match the dummy frame stack value
+previously saved using @code{SAVE_DUMMY_FRAME_TOS}.
+ at xref{SAVE_DUMMY_FRAME_TOS} dot
@item USE_STRUCT_CONVENTION (@var{gcc_p}, @var{type})
@findex USE_STRUCT_CONVENTION