Mail Archives: djgpp/2001/06/21/08:15:52
From: | invalid AT erehwon DOT invalid (Graaagh the Mighty)
|
Newsgroups: | comp.os.msdos.djgpp
|
Subject: | Strange behavior of compiler.
|
Organization: | Low Charisma Anonymous
|
Message-ID: | <3b31a377.174815003@news.primus.ca>
|
X-Newsreader: | Forte Free Agent 1.11/32.235
|
Lines: | 101
|
Date: | Thu, 21 Jun 2001 07:46:24 GMT
|
NNTP-Posting-Host: | 207.176.153.34
|
X-Complaints-To: | news AT primus DOT ca
|
X-Trace: | news2.tor.primus.ca 993109549 207.176.153.34 (Thu, 21 Jun 2001 03:45:49 EDT)
|
NNTP-Posting-Date: | Thu, 21 Jun 2001 03:45:49 EDT
|
To: | djgpp AT delorie DOT com
|
DJ-Gateway: | from newsgroup comp.os.msdos.djgpp
|
Reply-To: | djgpp AT delorie DOT com
|
I think I've found a bug in gcc 2.95.2.
I have a program (long) that contains something like:
int (*foo) (void);
...other variables...
int bar (void);
...other functions...
int main (void) {
...assorted setup -- no branches or gotos...
foo = bar; // Right at top level, outside of any conditionals.
...a bit of stuff...
if (foo()) {
...error message...
return -1;
}
...rest of job...
}
...assorted functions, including bar...
It dies with a segfault at the "if (foo()) {" line. The remarkable
thing is the following results from adding debugging printfs:
int (*foo) (void);
...other variables...
int bar (void);
...other functions...
int main (void) {
printf("%x\n", (int)bar);
...assorted setup -- no branches or gotos...
foo = bar; // Right at top level, outside of any conditionals.
...a bit of stuff...
printf("%x\n", (int)foo);
if (foo()) {
...error message...
return -1;
}
...rest of job...
}
The result?
3a30
3a30
Exiting due to signal SIGSEGV
Page fault at eip=01fc0000, error=0004
eax=01fc0000 ebx=ffffffff ecx=0000d854 edx=00004000 esi=000000ff
edi=00000000
ebp=004a9fb0 esp=004a9cc4 program=D:\QUICKM\BWLSM.EXE
cs: sel=00a7 base=83be4000 limit=ffa02fff
ds: sel=00af base=83be4000 limit=ffa02fff
es: sel=00af base=83be4000 limit=ffa02fff
fs: sel=0087 base=0000d830 limit=0000ffff
gs: sel=00bf base=00000000 limit=0010ffff
ss: sel=00af base=83be4000 limit=ffa02fff
App stack: [004aa000..0042a000] Exceptn stack: [00095428..000934e8]
Call frame traceback EIPs:
0x01fc0000 0x1fc0000
0x0000178b _main+275, line 195 of bwlsm.c
0x00057b7a ___crt1_startup+174
In other words, foo is 0x3a30 at the printf line, and 0x01fc0000 the
line right after.
C guarantees the order of evaluation here as follows: "foo" is
evaluated right before the printf call, then evaluated again right
before being jumped to in the if. Basically, the only way the value of
foo can be being clobbered is if the printf function is clobbering it,
which it can't be (it's passed by value), and besides, the fault
happens without the printf too!
This is with optimizations turned on out the wazoo, save for
-fomit-frame-pointer, which I removed to get a sensible traceback:
gcc bwlsm.c -o bwlsm.exe -lalleg -g -O6 -ffast-math -fforce-addr
-funroll-loops -march=k6 -malign-double -Wall -Werror
No warnings occurred. The fault still happens if I compile with a
mere:
gcc bwlsm.c -o bwlsm.exe -lalleg -g -Wall -Werror
i.e. only default optimizations, nothing whatsoever aggressive.
So, maybe the malloc arena, the stack, or something is getting
trashed? But it's dying *invoking* foo, not *returning* from it, and
all it does before calling foo at that fateful point is printf a few
things, compute the square root of three, and assign a few values to a
few variables. Not one single pointer-using instruction.
The weirdest thing is that the program worked fine until I added some
debugging printfs to bar, whereupon it started dying before it could
even *reach* bar...
--
Bill Gates: "No computer will ever need more than 640K of RAM." -- 1980
"There's nobody getting rich writing software that I know of." -- 1980
"This antitrust thing will blow over." -- 1998
Combine neo, an underscore, and one thousand sixty-one to make my hotmail addy.
- Raw text -