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]

[commit, oops] New function pc_in_dummy_frame(pc)


Hello,

This patch introduces a new function:

int pc_in_dummy_frame (CORE_ADDR pc);

The file frame.c is then updated to use either it, or (get_frame_type() == DUMMY_FRAME). The old generic_pc_in_call_dummy() took both a PC and an FP/SP, or generic dummy frames though (which all architectures should be using)

There is a problem though (and I only noticed after committing it :-().

The change assumes that all architectures that use generic dummy frames also set PC_IN_CALL_DUMMY to generic_pc_in_call_dummy() (and hence eventually call this new pc_in_dummy_frame). Problem is, some don't:
cris, frv, i386, x86-64
They instead use pc_in_call_dummy_at_entry_point(). Now, in theory, generic_pc_in_call_dummy() and pc_in_call_dummy_at_entry_point() are equivalent, I'm not going to put money on it though. Hence, expect a follow up patch to revert a small part of this change.

Andrew
2002-11-24  Andrew Cagney  <ac131313@redhat.com>

	* dummy-frame.c (pc_in_dummy_frame): New function.
	(generic_pc_in_call_dummy): Call pc_in_dummy_frame.
	(find_dummy_frame): Update comment.
	(generic_pop_current_frame): Use get_frame_type.
	* dummy-frame.h (pc_in_dummy_frame): Declare.
	* frame.c (set_unwind_by_pc): Use pc_in_dummy_frame.
	(create_new_frame): Use pc_in_dummy_frame.
	(get_prev_frame): Use pc_in_dummy_frame.
	(frame_saved_regs_register_unwind): Use get_prev_frame.
	(deprecated_generic_get_saved_register): Use get_prev_frame.

Index: dummy-frame.c
===================================================================
RCS file: /cvs/src/src/gdb/dummy-frame.c,v
retrieving revision 1.3
diff -u -r1.3 dummy-frame.c
--- dummy-frame.c	15 Nov 2002 22:16:25 -0000	1.3
+++ dummy-frame.c	24 Nov 2002 14:28:52 -0000
@@ -56,7 +56,7 @@
 /* Function: find_dummy_frame(pc, fp, sp)
 
    Search the stack of dummy frames for one matching the given PC and
-   FP/SP.  Unlike PC_IN_CALL_DUMMY, this function doesn't need to
+   FP/SP.  Unlike pc_in_dummy_frame(), this function doesn't need to
    adjust for DECR_PC_AFTER_BREAK.  This is because it is only legal
    to call this function after the PC has been adjusted.  */
 
@@ -139,6 +139,24 @@
 int
 generic_pc_in_call_dummy (CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR fp)
 {
+  return pc_in_dummy_frame (pc);
+}
+
+/* Return non-zero if the PC falls in a dummy frame.
+
+   The code below which allows DECR_PC_AFTER_BREAK is for infrun.c,
+   which may give the function a PC without that subtracted out.
+
+   FIXME: cagney/2002-11-23: This is silly.  Surely "infrun.c" can
+   figure out what the real PC (as in the resume address) is BEFORE
+   calling this function (Oh, and I'm not even sure that this function
+   is called with an decremented PC, the call to pc_in_call_dummy() in
+   that file is conditional on !CALL_DUMMY_BREAKPOINT_OFFSET_P yet
+   generic dummy targets set CALL_DUMMY_BREAKPOINT_OFFSET. True?).  */
+
+int
+pc_in_dummy_frame (CORE_ADDR pc)
+{
   struct dummy_frame *dummyframe;
   for (dummyframe = dummy_frame_stack;
        dummyframe != NULL;
@@ -241,8 +259,9 @@
 generic_pop_current_frame (void (*popper) (struct frame_info * frame))
 {
   struct frame_info *frame = get_current_frame ();
-
-  if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+  if (get_frame_type (frame) == DUMMY_FRAME)
+    /* NOTE: cagney/2002-22-23: Does this ever occure?  Surely a dummy
+       frame will have already been poped by the "infrun.c" code.  */
     generic_pop_dummy_frame ();
   else
     (*popper) (frame);
Index: dummy-frame.h
===================================================================
RCS file: /cvs/src/src/gdb/dummy-frame.h,v
retrieving revision 1.3
diff -u -r1.3 dummy-frame.h
--- dummy-frame.h	15 Nov 2002 22:16:25 -0000	1.3
+++ dummy-frame.h	24 Nov 2002 14:28:52 -0000
@@ -60,6 +60,31 @@
 extern CORE_ADDR dummy_frame_pc_unwind (struct frame_info *frame,
 					void **unwind_cache);
 
+/* Does the PC fall in a dummy frame?
+
+   This function is used by "frame.c" when creating a new `struct
+   frame_info'.
+
+   Note that there is also very similar code in breakpoint.c (where
+   the bpstat stop reason is computed).  It is looking for a PC
+   falling on a dummy_frame breakpoint.  Perhaphs this, and that code
+   should be combined?
+
+   Architecture dependant code, that has access to a frame, should not
+   use this function.  Instead (get_frame_type() == DUMMY_FRAME)
+   should be used.
+
+   Hmm, but what about threads?  When the dummy-frame code tries to
+   relocate a dummy frame's saved registers it definitly needs to
+   differentiate between threads (otherwize it will do things like
+   clean-up the wrong threads frames).  However, when just trying to
+   identify a dummy-frame that shouldn't matter.  The wost that can
+   happen is that a thread is marked as sitting in a dummy frame when,
+   in reality, its corrupted its stack, to the point that a PC is
+   pointing into a dummy frame.  */
+
+extern int pc_in_dummy_frame (CORE_ADDR pc);
+
 /* Return the regcache that belongs to the dummy-frame identifed by PC
    and FP, or NULL if no such frame exists.  */
 /* FIXME: cagney/2002-11-08: The function only exists because of
Index: frame.c
===================================================================
RCS file: /cvs/src/src/gdb/frame.c,v
retrieving revision 1.29
diff -u -r1.29 frame.c
--- frame.c	19 Nov 2002 00:46:00 -0000	1.29
+++ frame.c	24 Nov 2002 14:28:52 -0000
@@ -457,7 +457,7 @@
      dummy.  (generic_call_dummy_register_unwind ought to have been called
      instead.)  */
   gdb_assert (!(USE_GENERIC_DUMMY_FRAMES
-                && PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame)));
+		&& (get_frame_type (frame) == DUMMY_FRAME)));
 
   /* Load the saved_regs register cache.  */
   if (frame->saved_regs == NULL)
@@ -588,7 +588,7 @@
 
   while (frame && ((frame = frame->next) != NULL))
     {
-      if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+      if (get_frame_type (frame) == DUMMY_FRAME)
 	{
 	  if (lval)		/* found it in a CALL_DUMMY frame */
 	    *lval = not_lval;
@@ -656,7 +656,7 @@
       *unwind_register = frame_saved_regs_register_unwind;
       *unwind_pc = frame_saved_regs_pc_unwind;
     }
-  else if (PC_IN_CALL_DUMMY (pc, fp, fp))
+  else if (pc_in_dummy_frame (pc))
     {
       *unwind_register = dummy_frame_register_unwind;
       *unwind_pc = dummy_frame_pc_unwind;
@@ -694,7 +694,7 @@
      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 (USE_GENERIC_DUMMY_FRAMES && PC_IN_CALL_DUMMY (fi->pc, 0, 0))
+  if (USE_GENERIC_DUMMY_FRAMES && pc_in_dummy_frame (pc))
     /* NOTE: cagney/2002-11-11: Does this even occure?  */
     type = DUMMY_FRAME;
   else
@@ -976,7 +976,7 @@
      initialization, as seen in create_new_frame(), should occur
      before the INIT function has been called.  */
   if (USE_GENERIC_DUMMY_FRAMES
-      && PC_IN_CALL_DUMMY (prev->pc, 0, 0))
+      && pc_in_dummy_frame (prev->pc))
     prev->type = DUMMY_FRAME;
   else
     {

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