I've got a mixture of C++ and Fortran 77, all compiled with G77.
It is mostly C++, but it calls the ODE-solver DVERK, which then calls back to a global C function to get the derivative (declared with __stdcall
).
It's all been working fine, until I get a strange SIGSEGV.
I tracked that down, and it was because the esp
was decreasing below its segment boundary.
The reason it did that is that DVERK contains the **
operator, which internally is a function call with two double-precision values passed by value on the stack, for 16 bytes.
The function returns the answer, but then I see this instruction:
sub 0x10,%esp
which decrements the stack pointer by 16 bytes, as if it were putting the arguments back on the stack (?)
G77 seems to do this after every function call, and usually it does no harm because the stack pointer is unchanged.
However, in the case of **
the stack pointer remains decremented, and if that code is executed enough times, the decrementation adds up until I get the SIGSEGV.
(If there is sufficient stack space, this problem doesn't appear because the return from DVERK cleans it up.)
I tried replacing the code a**b
with dexp(dlog(a)*b)
, but the same thing happens, except it happens in two steps, 8 bytes after dlog
, and 8 bytes after dexp
.
There must be something I'm doing wrong in setting up the calling conventions used by G77 vis-a-vis its run-time-library. Expertise appreciated.