Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Mark Kettenis <kettenis@chello.nl>
To: gdb-patches@sources.redhat.com
Subject: [PATCH/RFC] Work around GCC compiler bugs in frame.c
Date: Thu, 15 Apr 2004 16:37:00 -0000	[thread overview]
Message-ID: <200404151637.i3FGbDHm000410@elgar.kettenis.dyndns.org> (raw)

I've always considered functions return a struct (as opposed to a
pointer to a struct) bad programming style, but now I know why.  The
following code in frame.c triggers a bug in the system compiler on
OpenBSD/vax (which is basically GCC 2.95.3 with some local patches):

      && frame_id_eq (get_frame_id (this_frame),
                      get_frame_id (this_frame->next))

The key here is that get_frame_id() returns a `struct frame_id'.  The
problem is that OpenBSD/vax is one of the GCC targets that define
PCC_STATIC_STRUCT_RETURN, which means that it uses a static buffer to
return the structure.  This static buffer is overwritten on each call.
This is exectly what happens here: the static buffer gets overwritten
by the second call to get_frame_id() before the result of the first
call is pushed on the stack as an argument to frame_id_eq().  The
result is that the frame_id_eq() always returns true :-(.  There are a
couple of other targets in GCC (mostly m68k), that might suffer from
the same problem.

I don't think it will be easy to fix the compiler bug, but it's not
too difficult to work around it in GDB; see the attached patch.
Actually I think the patch is an improvement since it may reduce the
number of calls to get_frame_id().

Oh, by the way, this PCC_STATIC_STRUCT_RETURN convention has
interesting consequences for the structs.exp testsuite; a lot of FAILs
:-(.  Wonder whether we need 

Comments?

Mark


Index: frame.c
===================================================================
RCS file: /cvs/src/src/gdb/frame.c,v
retrieving revision 1.170
diff -u -p -r1.170 frame.c
--- frame.c 2 Apr 2004 22:58:56 -0000 1.170
+++ frame.c 15 Apr 2004 16:05:54 -0000
@@ -1731,6 +1731,7 @@ legacy_get_prev_frame (struct frame_info
 static struct frame_info *
 get_prev_frame_1 (struct frame_info *this_frame)
 {
+  struct frame_id this_id = get_frame_id (this_frame);
   struct frame_info *prev_frame;
 
   gdb_assert (this_frame != NULL);
@@ -1769,7 +1770,7 @@ 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)))
+  if (this_frame->level >= 0 && !frame_id_p (this_id))
     {
       if (frame_debug)
 	{
@@ -1786,16 +1787,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.


             reply	other threads:[~2004-04-15 16:37 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-04-15 16:37 Mark Kettenis [this message]
2004-04-15 20:56 ` Andrew Cagney
2004-04-17 15:13   ` Mark Kettenis

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200404151637.i3FGbDHm000410@elgar.kettenis.dyndns.org \
    --to=kettenis@chello.nl \
    --cc=gdb-patches@sources.redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox