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]

[PATCH] Work around for GCC bug in frame.c


This patch works around a bug with GCC on some vax and m68k systems.
Andrew suggested introducing frame_eq() and frame_inner() and I
initially though that would be a good idea.  However, there are almost
no places where these functions would be used, so I dropped the idea.
I've now committed my origional patch.

Mark

Index: ChangeLog
from  Mark Kettenis  <kettenis@gnu.org>

	* frame.c (get_prev_frame_1): Work around GCC bug.
	* frame.h: Add comment about GCC bug.

Index: frame.c
===================================================================
RCS file: /cvs/src/src/gdb/frame.c,v
retrieving revision 1.178
diff -u -p -r1.178 frame.c
--- frame.c 1 May 2004 22:41:34 -0000 1.178
+++ frame.c 7 May 2004 23:13:48 -0000
@@ -1609,6 +1609,7 @@ static struct frame_info *
 get_prev_frame_1 (struct frame_info *this_frame)
 {
   struct frame_info *prev_frame;
+  struct frame_id this_id;
 
   gdb_assert (this_frame != NULL);
 
@@ -1646,7 +1647,8 @@ get_prev_frame_1 (struct frame_info *thi
   /* Check that this frame's ID was valid.  If it wasn't, don't try to
      unwind to the prev frame.  Be careful to not apply this test to
      the sentinel frame.  */
-  if (this_frame->level >= 0 && !frame_id_p (get_frame_id (this_frame)))
+  this_id = get_frame_id (this_frame);
+  if (this_frame->level >= 0 && !frame_id_p (this_id))
     {
       if (frame_debug)
 	{
@@ -1663,16 +1665,14 @@ get_prev_frame_1 (struct frame_info *thi
      go backwards) and sentinel frames (the test is meaningless).  */
   if (this_frame->next->level >= 0
       && this_frame->next->type != SIGTRAMP_FRAME
-      && frame_id_inner (get_frame_id (this_frame),
-			 get_frame_id (this_frame->next)))
+      && frame_id_inner (this_id, get_frame_id (this_frame->next)))
     error ("Previous frame inner to this frame (corrupt stack?)");
 
   /* Check that this and the next frame are not identical.  If they
      are, there is most likely a stack cycle.  As with the inner-than
      test above, avoid comparing the inner-most and sentinel frames.  */
   if (this_frame->level > 0
-      && frame_id_eq (get_frame_id (this_frame),
-		      get_frame_id (this_frame->next)))
+      && frame_id_eq (this_id, get_frame_id (this_frame->next)))
     error ("Previous frame identical to this frame (corrupt stack?)");
 
   /* Allocate the new frame but do not wire it in to the frame chain.
Index: frame.h
===================================================================
RCS file: /cvs/src/src/gdb/frame.h,v
retrieving revision 1.132
diff -u -p -r1.132 frame.h
--- frame.h 1 May 2004 22:41:34 -0000 1.132
+++ frame.h 7 May 2004 23:13:48 -0000
@@ -310,7 +310,22 @@ extern CORE_ADDR get_frame_base (struct 
 
 /* Return the per-frame unique identifer.  Can be used to relocate a
    frame after a frame cache flush (and other similar operations).  If
-   FI is NULL, return the null_frame_id.  */
+   FI is NULL, return the null_frame_id.
+
+   NOTE: kettenis/20040508: These functions return a structure.  On
+   platforms where structures are returned in static storage (vax,
+   m68k), this may trigger compiler bugs in code like:
+
+   if (frame_id_eq (get_frame_id (l), get_frame_id (r)))
+
+   where the return value from the first get_frame_id (l) gets
+   overwritten by the second get_frame_id (r).  Please avoid writing
+   code like this.  Use code like:
+
+   struct frame_id id = get_frame_id (l);
+   if (frame_id_eq (id, get_frame_id (r)))
+
+   instead, since that avoids the bug.  */
 extern struct frame_id get_frame_id (struct frame_info *fi);
 extern struct frame_id frame_unwind_id (struct frame_info *next_frame);
 


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