First I've a singleton.cpp file to build a singleton object, and declare instance using attribute((constructor))
#include<iostream>
using namespace std;
class singleton{
public:
singleton(){cout<<"singleton ctor\n";}
};
__attribute__((constructor)) static void beforeFunction()
{
printf("beforeFunction\n");
singleton obj;
}
And a simple main.cpp
#include<iostream>
using namespace std;
int main(){
return 0;
}
I build main.cpp singleton.cpp together:
g++ singleton.cpp main.cpp -o main
./main
beforeFunction
Segmentation fault
So why my program crashes, what happened? How to fix it? I'm using gcc on ubuntu. Thanks a lot.
I reproduced this with g++ (Debian 7.3.0-5)
, and also g++ (GCC) 9.0.0 20180902 (experimental)
.
It's interesting that this fails:
$ g++ singleton.cpp main.cpp && ./a.out
beforeFunction
Segmentation fault
but this works as expected:
$ g++ main.cpp singleton.cpp && ./a.out
beforeFunction
singleton ctor
As Acorn correctly stated, the iostream
/ std::cout
machinery has not been properly initialized by the time you called singleton constructor. This is happening because there is special code emitted into main.o
(and only main.o
) which calls std::ios_base::Init::Init()
. And only because main.cpp
has extraneous #include <iostream>
.
How to fix it?
The best fix is to not use __attribute__((constructor))
at all. In your case, there is no reason to do what you are doing. Do this instead:
// singleton2.cpp
#include<iostream>
using namespace std;
class singleton{
public:
singleton(){cout<<"singleton ctor\n";}
};
static singleton obj;
With above code, either order of linking works:
$ g++ main.cpp singleton2.cpp && ./a.out
singleton ctor
$ g++ singleton2.cpp main.cpp && ./a.out
singleton ctor
If you insist on using __attribute__((constructor))
, then make sure main.o
is on your link line before any other object that could use iostream
s.