I have a mixed Free Pascal/C++ project. Debian 5.0 ("Lenny") on i386, FPC 2.4.4. When I run the program, it crashes on the first cout<<
call. Funnily, it used to work for some time; some OS update probably broke it. Here's the issue isolated:
p.pas:
{$L c.o}
program p;
uses initc;
procedure Hello; cdecl; external name 'Hello';
begin
Hello;
end.
c.cpp:
#include <iostream>
//void * __dso_handle; //You might need to uncomment that
extern "C" void Hello()
{
std::cout << "Hello world";
}
Makefile:
p : c.o p.pas Makefile
fpc p.pas -k-lstdc++
c.o : c.cpp
g++ -c c.cpp
Make, run, segfault. Tried on a brand new Debian VM - same result.
The crash takes place within basic_fstream::sentry::sentry(). They claim this crash location is consistent with the global cout
object not being initialized. That's strange - I thought using initc
from the Pascal side makes sure global C++ variables are initialized.
Any ideas, please? Could it be somehow the version of libstdc++ I'm linking against (it's libstdc++.so.6.0.10)?
EDIT: it gets weirder and weirder. I run the same binary (p
) on a CentOS 5.3 box - it works as advertised. So probably it's about shared lib versions... I'll go gather some more stats on different Linuces.
EDIT2: one thing I noticed: when I do ldd p
on my Debian box, here's what I get:
linux-gate.so.1 => (0xb77a6000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb76a6000)
libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb754b000)
libm.so.6 => /lib/i686/cmov/libm.so.6 (0xb7524000)
/lib/ld-linux.so.2 (0xb77a7000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7517000)
And when I do the same on the CentOS box where it works:
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb7ec2000)
libc.so.6 => /lib/libc.so.6 (0xb7d69000)
libm.so.6 => /lib/libm.so.6 (0xb7d40000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7d34000)
/lib/ld-linux.so.2 (0xb7fb7000)
So all C libraries (just not the C++ one) are coming from i686/cmov
directory. The Debian machine also has /lib/libc.so.6
, and it's different from the one in cmov
. What's the deal with that cmov
directory? And why two different copies of libc with the same name?
EDIT: even on CentOS, the global constructors are not called - just tested with an ad-hoc global object. It just does not crash in sentry() for some reason. Looks like this is a FPC issue after all. There's a bug report in FPC regarding this behavior.