This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
A possible bug in g++ w/ -O option (SPARC)
- To: "gcc-bugs at gcc dot gnu dot org" <gcc-bugs at gcc dot gnu dot org>
- Subject: A possible bug in g++ w/ -O option (SPARC)
- From: "Aki Niimura" <neko at my-Deja dot com>
- Date: Sun, 12 Dec 1999 20:01:13 -0800
- Organization: My Deja Email (http://www.my-deja.com:80)
Hi everyone,
I have been writing an application specific simulation
using C++ language. C++ allows me to write a simulation model
quite easily thanks to Object Oriented concept.
Anyway, my simulation program works fine under the following
environments:
<Sparc / Solaris7>
- w/o -O (no optimization)
<x86 / Solaris7>
- w/o -O (no optimization)
- w/ -O (optimization)
But it generates core dump under the following environment:
<Sparc / Solaris7>
- w/ -O (optimization)
% top <-- my simulation executable
Segmentation Fault (core dumped)
%
I have been using g++ for this simulation for almost two years.
I think the version of g++ back then is 2.6.??.
And currently, I'm using g++ 2.95.2.
I have been waiting for somebody fixes this problem, but it
seems not happening. So I tried to track down the problem by
myself. Unfortunately, I can't come up with a small sample
program which reproduces the problem. But I think I understand
the problem.
My simulation uses longjmp and setjmp to implement $delay(n),
which controls the execution of the simulation.
(ex.)
cout << "a" << endl; // executed at T = T0
$delay(2); // implemented in macro
cout << "b" << endl; // executed at T = T0+2
The above code fragment is actually:
void
Model::exec()
{
static jmp_buf $env;
static tick_t $till;
static bool $magic;
if($magic) longjmp($env, 1);
$cout << "a" << endl; // executed at T = T0
// $delay(2);
$till=$time+(2);
$setjmp($env);
if($time != $till) return;
$magic = false;
$cout << "b" << endl; // executed at T = T0+2
}
What's happening when it is compiled with -O option is:
(1) Using gdb, I traced the program instruction by instruction
sethi %hi($magic.980), %o0
ld [%o0+%lo($magic.980)], %o0
cmp %o0, 0
be,a .LL2411
sethi %hi($cout+84), %o0
sethi %hi($env.978), %o0
or %o0, %lo($env.978), %o0
call longjmp, 0 <<--- (a)
mov 1, %o1
.LL2411:
or %o0, %lo($cout+84), %o0
sethi %hi(.LLC21), %o1
call __ls__7ostreamPCc, 0
or %o1, %lo(.LLC21), %o1
call endl__FR7ostream, 0
sethi %hi($till.979), %l0 <<--- (b)
sethi %hi($time), %o0
or %o0, %lo($time), %o1
ld [%o0+%lo($time)], %o0
call .umul, 0
ld [%o1+4], %o1
add %o0, 10, %o0
st %o0, [%l0+%lo($till.979)]
sethi %hi($magic.980), %o1
mov 1, %o0
st %o0, [%o1+%lo($magic.980)]
sethi %hi($env.978), %o0
call setjmp, 0 <<--- (c)
or %o0, %lo($env.978), %o0
sethi %hi($time), %l1
or %l1, %lo($time), %l3
ld [%l1+%lo($time)], %o0
call .umul, 0
ld [%l3+4], %o1
sethi %hi($till.979), %l0
mov %l0, %l2
ld [%l0+%lo($till.979)], %o1 <<<<<-- this is the location of SIGSEGV
cmp %o0, %o1
bne .LL2410
sethi %hi($magic.980), %l0
st %g0, [%l0+%lo($magic.980)]
sethi %hi($cout+84), %o0
(2) %l0 register value
When it generates SIGSEGV, the value of %l0 is 0x0 which is obviously
wrong.
(3) %l0 is set at (b) but because of longjmp - setjmp branch,
the program skips from (a) to (c) thus %l0 is not set correctly.
(4) g++ compiler does register allocation and check its validity.
However, g++ seems ignore the possible branch due to longjmp -
setjmp.
(5) I put an extra instruction which sets %l0 register and it works.
sethi %hi($till.979), %l0 <<--- extra instruction
mov %l0, %l2
ld [%l0+%lo($till.979)], %o1 <<<<<-- this is the location of SIGSEGV
cmp %o0, %o1
(6) I also put $env, $till, $magic into class member variables.
And this case works.
jmp_buf $env; // no longer static
tick_t $till;
bool $magic;
void exec();
}
I definitely want to use -O option because it brings significant
simulation speed up. I look forward to g++ future release with
this problem fixed.
Best regards,
Aki Niimura
--== Sent via Deja.com http://www.deja.com/ ==--
Share what you know. Learn what you don't.