* [PATCH/RFC] Work around GCC compiler bugs in frame.c
@ 2004-04-15 16:37 Mark Kettenis
2004-04-15 20:56 ` Andrew Cagney
0 siblings, 1 reply; 3+ messages in thread
From: Mark Kettenis @ 2004-04-15 16:37 UTC (permalink / raw)
To: gdb-patches
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.
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH/RFC] Work around GCC compiler bugs in frame.c
2004-04-15 16:37 [PATCH/RFC] Work around GCC compiler bugs in frame.c Mark Kettenis
@ 2004-04-15 20:56 ` Andrew Cagney
2004-04-17 15:13 ` Mark Kettenis
0 siblings, 1 reply; 3+ messages in thread
From: Andrew Cagney @ 2004-04-15 20:56 UTC (permalink / raw)
To: Mark Kettenis; +Cc: gdb-patches
> 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))
Would introducing frame_eq(), frame_inner() be more robust? Either way
you'll likely want to add a comment.
Andrew
(I knew that there had been a bug but no one I asked could remember or
demonstrate it.).
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH/RFC] Work around GCC compiler bugs in frame.c
2004-04-15 20:56 ` Andrew Cagney
@ 2004-04-17 15:13 ` Mark Kettenis
0 siblings, 0 replies; 3+ messages in thread
From: Mark Kettenis @ 2004-04-17 15:13 UTC (permalink / raw)
To: cagney; +Cc: gdb-patches
Date: Thu, 15 Apr 2004 16:56:04 -0400
From: Andrew Cagney <cagney@gnu.org>
> 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))
Would introducing frame_eq(), frame_inner() be more robust? Either way
you'll likely want to add a comment.
That would make sense I guess. It's the frame that we care about, not
the ID. I'll check wrap something up...
Mark
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2004-04-17 15:13 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-04-15 16:37 [PATCH/RFC] Work around GCC compiler bugs in frame.c Mark Kettenis
2004-04-15 20:56 ` Andrew Cagney
2004-04-17 15:13 ` Mark Kettenis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox