Subject: Re: Global variable name which equals to func name causes coredump(gcc).
To: None <bianshaolei@gmail.com>
From: Ignatios Souvatzis <ignatios@cs.uni-bonn.de>
List: tech-userlevel
Date: 09/27/2007 12:34:10
On Thu, Sep 27, 2007 at 06:04:05PM +0800, ?????? wrote:
> Hi, all.
> Please see a simple program as list:
> cat a.c:
>  #include <stdio.h>
>     int read;
>     int main()
>     {
>         printf("%p\n", &read);
>         char buf[1024];
>         FILE * fp = fopen("a.c", "r");
>         int len = fread(buf, 1, 1024, fp);
>         buf[len] = 0;
>         printf("%s\n", buf);
>         return 0;
>     }
> ======
> gcc a.c -ggdb -Wall #There was no warning.
> ======
> ./a.out
> ======
> 0x80499f8
> (coredump)
> ======
> gdb a.out -c a.out.core
> #0  0x080499f8 in read ()
> (gdb) where
> #0  0x080499f8 in read ()
> #1  0xbbbc6435 in __sread () from /usr/lib/libc.so.12
> #2  0xbbbafc39 in __srefill () from /usr/lib/libc.so.12
> #3  0xbbbaa92b in fread () from /usr/lib/libc.so.12
> #4  0x0804879e in main () at a.c:7
> ======
> Obviously fread called the wrong func address of read.
> 
> 
> 
> See another simpler program:
> cat b.c
> ======
> int mlock;
> int main()
> {
> }
> =====
> gcc b.c -lpthread -o b.out
> =====
> ./b.out
> (coredump)
> 
> b.out did not even run to func main before it coredumped. I guess
> libpthread.so need to run func mlock when loaded (maybe in _init), but
> in my program mlock is just an integer -- not a func.
> 
> =====
> =====
> =====
> I have tested two program above in FreeBSD, OpenBSD, Mingw+gcc4.2.1
> and ubuntu 7.04 with gcc 4. None of others had the same problem.
> 
> I met the second problem in 2006. But at that time I was compling a
> big project (RGTK) and did not know where the problem was (At that
> time I used NetBSD amd64 3.0).
> 
> Is this a bug, or something I miss to understand it?

Works as expected.

There is only one name space at link time - global variable names can
shadow function names when the functions are defined in a library, and
as your program defined the name "read", the function "read" from the
library wasn't linked in. So... fread could only call the "read"
variables address, crashing the program.

If you want a language where the compiler knows about all symbols, you
know where to find, for example, Haskell. C with seperate compilation
units isn't what you're looking after.

I *think* that "lint" might have found the condition. But -
the linker can't complain, because it doesn't have type information, and
it did find a "read" symbol after all. And cc can't find the error, either,
because the call to "read" isn't visible in your compilation unit, and
your read wasn't visible to the compiler that compiled "fread".

Regards,
	-is