* frame.c (get_prev_frame_1): Work around GCC bug.
authorMark Kettenis <kettenis@gnu.org>
Fri, 7 May 2004 23:19:14 +0000 (23:19 +0000)
committerMark Kettenis <kettenis@gnu.org>
Fri, 7 May 2004 23:19:14 +0000 (23:19 +0000)
* frame.h: Add comment about GCC bug.

gdb/ChangeLog
gdb/frame.c
gdb/frame.h

index d7d33e6..8fb8c98 100644 (file)
@@ -1,3 +1,8 @@
+2004-05-08  Mark Kettenis  <kettenis@gnu.org>
+
+       * frame.c (get_prev_frame_1): Work around GCC bug.
+       * frame.h: Add comment about GCC bug.
+
 2004-05-07  Andrew Cagney  <cagney@redhat.com>
 
        * observer.c: Include "commands.h" and "gdbcmd.h".
index 8fb0344..eba8605 100644 (file)
@@ -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 *this_frame)
   /* 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 *this_frame)
      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 2ab8b8e..55d357c 100644 (file)
@@ -310,7 +310,22 @@ extern CORE_ADDR get_frame_base (struct frame_info *);
 
 /* 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);