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]

[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

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