* Suggestion: Detect inconsistent structure definitions
@ 2002-03-13 10:22 Zack Weinberg
2002-03-13 10:40 ` Kris Warkentin
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Zack Weinberg @ 2002-03-13 10:22 UTC (permalink / raw)
To: gdb
Consider the following two source files:
-- a.c --
struct A {
int a;
int b;
};
struct A a = { 1, 2 };
-- b.c --
struct A {
char a;
char b;
};
extern struct A a;
int main(void) {
if (a.a == 1 && b.a == 2)
return 0;
else
return 1;
}
--
It is obvious that the complete program consisting of these two files
is buggy: the declarations of struct A do not match. However, the
program will compile, link, and execute with no complaints, just an
unexpected return value.
When the program is large and complicated, this sort of bug can be
near-impossible to find, especially when the structure type
declaration _is_ properly isolated in a header file, but other headers
(possibly from third-party libraries) have issued inconsistent
typedefs/#defines for the aggregate's member types. I just spent two
days chasing exactly this problem in an INN installation.
The compiler and linker do not have enough information to detect the
bug, but gdb does; each object file's debug info will contain a type
declaration for struct A, and they won't match. With stabs, it's
obvious just doing
$ strings -a a.out | grep '^A:'
A:T(0,20)=s8a:(0,1),0,32;b:(0,1),32,32;;
A:T(0,20)=s2a:(0,2),0,8;b:(0,2),8,8;;
I can see the same thing in readelf -w output when DWARF2 is used,
although more verbosely.
It Would Be Nice if gdb would notice this and print a warning message,
along the lines of
warning: type `struct A' defined inconsistently in object files `a.o'
and `b.o'
when started up.
zw
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: Suggestion: Detect inconsistent structure definitions
2002-03-13 10:22 Suggestion: Detect inconsistent structure definitions Zack Weinberg
@ 2002-03-13 10:40 ` Kris Warkentin
2002-03-13 16:02 ` Daniel Jacobowitz
2002-03-13 16:07 ` Daniel Jacobowitz
[not found] ` <mailpost.1016043761.7328@news-sj1-1>
2 siblings, 1 reply; 9+ messages in thread
From: Kris Warkentin @ 2002-03-13 10:40 UTC (permalink / raw)
To: gdb, Zack Weinberg
Seems to me that the linker should be able to detect this problem as
well....It uses the debug information for error reporting. The problem here
is not so much the definitions of the structures but the reference to a
variable defined in another object which has a different definition.
Perhaps some smart checking would only look at external references and see
if they have compatable definitions rather than just looking at definitions.
That being said, I'd love to see that myself - we have some defines that
cause things in our headers (particularily things like struct stat) to be 32
or 64 bit on some of it's fields. That can wreak some serious havoc if your
lib and app are compiled with different flags.
cheers,
Kris
----- Original Message -----
From: "Zack Weinberg" <zack@codesourcery.com>
To: <gdb@sources.redhat.com>
Sent: Wednesday, March 13, 2002 1:22 PM
Subject: Suggestion: Detect inconsistent structure definitions
> Consider the following two source files:
>
> -- a.c --
> struct A {
> int a;
> int b;
> };
>
> struct A a = { 1, 2 };
>
> -- b.c --
> struct A {
> char a;
> char b;
> };
>
> extern struct A a;
>
> int main(void) {
> if (a.a == 1 && b.a == 2)
> return 0;
> else
> return 1;
> }
>
> --
> It is obvious that the complete program consisting of these two files
> is buggy: the declarations of struct A do not match. However, the
> program will compile, link, and execute with no complaints, just an
> unexpected return value.
>
> When the program is large and complicated, this sort of bug can be
> near-impossible to find, especially when the structure type
> declaration _is_ properly isolated in a header file, but other headers
> (possibly from third-party libraries) have issued inconsistent
> typedefs/#defines for the aggregate's member types. I just spent two
> days chasing exactly this problem in an INN installation.
>
> The compiler and linker do not have enough information to detect the
> bug, but gdb does; each object file's debug info will contain a type
> declaration for struct A, and they won't match. With stabs, it's
> obvious just doing
>
> $ strings -a a.out | grep '^A:'
> A:T(0,20)=s8a:(0,1),0,32;b:(0,1),32,32;;
> A:T(0,20)=s2a:(0,2),0,8;b:(0,2),8,8;;
>
> I can see the same thing in readelf -w output when DWARF2 is used,
> although more verbosely.
>
> It Would Be Nice if gdb would notice this and print a warning message,
> along the lines of
>
> warning: type `struct A' defined inconsistently in object files `a.o'
> and `b.o'
>
> when started up.
>
> zw
>
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: Suggestion: Detect inconsistent structure definitions
2002-03-13 10:40 ` Kris Warkentin
@ 2002-03-13 16:02 ` Daniel Jacobowitz
2002-03-14 5:14 ` Kris Warkentin
0 siblings, 1 reply; 9+ messages in thread
From: Daniel Jacobowitz @ 2002-03-13 16:02 UTC (permalink / raw)
To: Kris Warkentin; +Cc: gdb, Zack Weinberg
On Wed, Mar 13, 2002 at 01:41:16PM -0500, Kris Warkentin wrote:
> Seems to me that the linker should be able to detect this problem as
> well....It uses the debug information for error reporting. The problem here
No, the linker uses symbol information. It does -not- read debug info.
> is not so much the definitions of the structures but the reference to a
> variable defined in another object which has a different definition.
That's just a specific case of the problem Zack is describing, really.
--
Daniel Jacobowitz Carnegie Mellon University
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Suggestion: Detect inconsistent structure definitions
2002-03-13 16:02 ` Daniel Jacobowitz
@ 2002-03-14 5:14 ` Kris Warkentin
0 siblings, 0 replies; 9+ messages in thread
From: Kris Warkentin @ 2002-03-14 5:14 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb, Zack Weinberg
----- Original Message -----
From: "Daniel Jacobowitz" <drow@mvista.com>
To: "Kris Warkentin" <kewarken@qnx.com>
Cc: <gdb@sources.redhat.com>; "Zack Weinberg" <zack@codesourcery.com>
Sent: Wednesday, March 13, 2002 7:02 PM
Subject: Re: Suggestion: Detect inconsistent structure definitions
> On Wed, Mar 13, 2002 at 01:41:16PM -0500, Kris Warkentin wrote:
> > Seems to me that the linker should be able to detect this problem as
> > well....It uses the debug information for error reporting. The problem
here
>
> No, the linker uses symbol information. It does -not- read debug info.
I'm not so sure about that. I remember a problem with gnu ld crashing in
the dwarf1 interpretation section of the bfd when it couldn't resolve a
symbol. - if you link an app without debug info you will get different error
messages from ld than if it does have debug info. You may be right in that
it doesn't read the debug info while it's linking - I think it only looks at
it if there's an error so that it can print nicer error messages (ie. source
file/line # vs. object)
>
> > is not so much the definitions of the structures but the reference to a
> > variable defined in another object which has a different definition.
>
> That's just a specific case of the problem Zack is describing, really.
I spent some time thinking about that and you're right - there's WAY too
many ways that a reference to a structure could pass across object
boundaries to check for them all. The best we could do is to optionally
give warnings if structures of the same name and different format are
described in different objects. One would think that, in practice, this
wouldn't come up that often and would most likely be a sign of a problem.
cheers,
Kris
>
> --
> Daniel Jacobowitz Carnegie Mellon University
> MontaVista Software Debian GNU/Linux Developer
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Suggestion: Detect inconsistent structure definitions
2002-03-13 10:22 Suggestion: Detect inconsistent structure definitions Zack Weinberg
2002-03-13 10:40 ` Kris Warkentin
@ 2002-03-13 16:07 ` Daniel Jacobowitz
2002-03-14 11:13 ` Zack Weinberg
[not found] ` <mailpost.1016043761.7328@news-sj1-1>
2 siblings, 1 reply; 9+ messages in thread
From: Daniel Jacobowitz @ 2002-03-13 16:07 UTC (permalink / raw)
To: Zack Weinberg; +Cc: gdb
On Wed, Mar 13, 2002 at 10:22:22AM -0800, Zack Weinberg wrote:
> Consider the following two source files:
>
> -- a.c --
> struct A {
> int a;
> int b;
> };
>
> struct A a = { 1, 2 };
>
> -- b.c --
> struct A {
> char a;
> char b;
> };
>
> extern struct A a;
>
> int main(void) {
> if (a.a == 1 && b.a == 2)
> return 0;
> else
> return 1;
> }
>
> --
> It is obvious that the complete program consisting of these two files
> is buggy: the declarations of struct A do not match. However, the
> program will compile, link, and execute with no complaints, just an
> unexpected return value.
>
> When the program is large and complicated, this sort of bug can be
> near-impossible to find, especially when the structure type
> declaration _is_ properly isolated in a header file, but other headers
> (possibly from third-party libraries) have issued inconsistent
> typedefs/#defines for the aggregate's member types. I just spent two
> days chasing exactly this problem in an INN installation.
>
> The compiler and linker do not have enough information to detect the
> bug, but gdb does; each object file's debug info will contain a type
> declaration for struct A, and they won't match. With stabs, it's
> obvious just doing
It's not clear that GDB does. Consider a slightly modified example:
> -- a.c --
> struct A {
> int a;
> int b;
> };
>
> static struct A a = { 1, 2 };
>
> -- b.c --
> struct A {
> char a;
> char b;
> };
>
> static struct A a = {3, 4};
>
> int main(void) {
> if (a.a == 1 && b.a == 2)
> return 0;
> else
> return 1;
> }
>
> --
OK, that's a somewhat degenerate case, but my point holds. When do we
have enough information to know that two references are 'supposed' to
be of the same type, rather than an implementation-private type? And in
stabs, at least, no debug information appears to be emitted for
'extern' statements, so we don't know if a file referenced the type it
had a different definition of or not.
Perhaps a command to show types with multiple different definitions?
Please file a GNATS PR so that this idea doesn't get forgotten.
--
Daniel Jacobowitz Carnegie Mellon University
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: Suggestion: Detect inconsistent structure definitions
2002-03-13 16:07 ` Daniel Jacobowitz
@ 2002-03-14 11:13 ` Zack Weinberg
2002-03-14 21:03 ` Daniel Jacobowitz
0 siblings, 1 reply; 9+ messages in thread
From: Zack Weinberg @ 2002-03-14 11:13 UTC (permalink / raw)
To: gdb
On Wed, Mar 13, 2002 at 07:07:08PM -0500, Daniel Jacobowitz wrote:
>
> ... When do we have enough information to know that two references
> are 'supposed' to be of the same type, rather than an
> implementation-private type? And in stabs, at least, no debug
> information appears to be emitted for 'extern' statements, so we
> don't know if a file referenced the type it had a different
> definition of or not.
I would argue that this situation is rare, and that most programmers
are unlikely to think of incompatible structure definitions as the
cause of a bug. Therefore, how about a warning issued by default when
the object file is read, but with a way to shut it up per-structure in
.gdbinit?
> Please file a GNATS PR so that this idea doesn't get forgotten.
Done, #420.
zw
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Suggestion: Detect inconsistent structure definitions
2002-03-14 11:13 ` Zack Weinberg
@ 2002-03-14 21:03 ` Daniel Jacobowitz
2002-03-14 22:11 ` Andrew Cagney
0 siblings, 1 reply; 9+ messages in thread
From: Daniel Jacobowitz @ 2002-03-14 21:03 UTC (permalink / raw)
To: Zack Weinberg; +Cc: gdb
On Thu, Mar 14, 2002 at 11:13:37AM -0800, Zack Weinberg wrote:
> On Wed, Mar 13, 2002 at 07:07:08PM -0500, Daniel Jacobowitz wrote:
> >
> > ... When do we have enough information to know that two references
> > are 'supposed' to be of the same type, rather than an
> > implementation-private type? And in stabs, at least, no debug
> > information appears to be emitted for 'extern' statements, so we
> > don't know if a file referenced the type it had a different
> > definition of or not.
>
> I would argue that this situation is rare, and that most programmers
> are unlikely to think of incompatible structure definitions as the
> cause of a bug. Therefore, how about a warning issued by default when
> the object file is read, but with a way to shut it up per-structure in
> .gdbinit?
I would wager a guess that this occurs at least once or twice in glibc,
somewhere. Or in some other system's system libraries. Or in the
application package some hundred graphics applications are using. Or
something along those lines.
In any case, PR filed, hopefully someone will have time and look at it
soon.
--
Daniel Jacobowitz Carnegie Mellon University
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Suggestion: Detect inconsistent structure definitions
2002-03-14 21:03 ` Daniel Jacobowitz
@ 2002-03-14 22:11 ` Andrew Cagney
0 siblings, 0 replies; 9+ messages in thread
From: Andrew Cagney @ 2002-03-14 22:11 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: Zack Weinberg, gdb
> I would argue that this situation is rare, and that most programmers
>> are unlikely to think of incompatible structure definitions as the
>> cause of a bug. Therefore, how about a warning issued by default when
>> the object file is read, but with a way to shut it up per-structure in
>> .gdbinit?
>
>
> I would wager a guess that this occurs at least once or twice in glibc,
> somewhere. Or in some other system's system libraries. Or in the
> application package some hundred graphics applications are using. Or
> something along those lines.
>
> In any case, PR filed, hopefully someone will have time and look at it
> soon.
BTW, it is a valid C (but invalid C++) construct. It occures in GDB.
Andrew
^ permalink raw reply [flat|nested] 9+ messages in thread
[parent not found: <mailpost.1016043761.7328@news-sj1-1>]
* Re: Suggestion: Detect inconsistent structure definitions
[not found] ` <mailpost.1016043761.7328@news-sj1-1>
@ 2002-03-13 18:35 ` cgd
0 siblings, 0 replies; 9+ messages in thread
From: cgd @ 2002-03-13 18:35 UTC (permalink / raw)
To: zack; +Cc: gdb, gcc
At Wed, 13 Mar 2002 18:22:41 +0000 (UTC), "Zack Weinberg" wrote:
> Consider the following two source files:
>
> -- a.c --
> struct A {
> int a;
> int b;
> };
>
> struct A a = { 1, 2 };
>
> -- b.c --
> struct A {
> char a;
> char b;
> };
>
> extern struct A a;
>
> int main(void) {
> if (a.a == 1 && b.a == 2)
> return 0;
> else
> return 1;
> }
>
> --
> It is obvious that the complete program consisting of these two files
> is buggy: the declarations of struct A do not match. However, the
> program will compile, link, and execute with no complaints, just an
> unexpected return value.
>
> When the program is large and complicated, this sort of bug can be
> near-impossible to find, especially when the structure type
> declaration _is_ properly isolated in a header file, but other headers
> (possibly from third-party libraries) have issued inconsistent
> typedefs/#defines for the aggregate's member types. I just spent two
> days chasing exactly this problem in an INN installation.
>
> The compiler and linker do not have enough information to detect the
> bug, but gdb does [ ... ]
I believe that this type of bug will typically be discovered by proper
application of 'lint'.
There are open-source versions of lint out there... (I dunno what
OSes ship them, but NetBSD definitely does.)
If you want to solve this problem in the context of the gcc and
related tools, my personal thought as to "the right thing" would be to
create a mode for gcc which can output lint-like information instead
of object code, and then create an external program to merge that
information.
(this is what lint does: in the first 'pass' it has a C parser, etc.,
and parses the C code and can output lint files (instead of .o files).
then, another pass merges that all together and produces final results
/ warnings.)
If you did the first pass inside GCC, you might even be able to do it
so that it would even work/interoperate for languages other than C.
8-)
chris
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2002-03-15 6:11 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-03-13 10:22 Suggestion: Detect inconsistent structure definitions Zack Weinberg
2002-03-13 10:40 ` Kris Warkentin
2002-03-13 16:02 ` Daniel Jacobowitz
2002-03-14 5:14 ` Kris Warkentin
2002-03-13 16:07 ` Daniel Jacobowitz
2002-03-14 11:13 ` Zack Weinberg
2002-03-14 21:03 ` Daniel Jacobowitz
2002-03-14 22:11 ` Andrew Cagney
[not found] ` <mailpost.1016043761.7328@news-sj1-1>
2002-03-13 18:35 ` cgd
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox