I'm trying to design a library. To support different link type, I've tested static-link, dynamic-link directly and open sharing library. For the third way, it seems the code will failure on creating the thread after using dlopen()
to open the library and get the address of the function with dlsym()
. But the static-link and dynamic-link would be of no problem.
The main part of the function is:
class test_t
{
public:
test_t(){}
static test_t& get_instance()
{
static test_t t;
return t;
}
void process()
{
}
void detach()
{
auto t = std::thread([]{
auto& d = test_t::get_instance();
while(true)
{
d.process();
}
});
std::cout << t.get_id() << std::endl;
t.detach();
}
private:
};
extern "C" void init()
{
test_t::get_instance().detach();
}
The call-stack case when segment fault is:
#0 0x0000000000000000 in ?? ()
#1 0x00007ffff79059a5 in std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) ()
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#2 0x00007ffff6c9dc4b in std::thread::thread<test_t::detach()::{lambda()#1}, , void>(test_t::detach()::{lambda()#1}&&) (this=0x7fffffffe150, __f=...)
at /usr/include/c++/8/thread:131
#3 0x00007ffff6c9daf5 in test_t::detach (this=0x7ffff6ea0262 <test_t::get_instance()::t>) at /test/a.cpp:28
#4 0x00007ffff6c9d906 in init () at /test/a.cpp:37
#5 0x0000555555554ac0 in main (argc=1, argv=0x7fffffffe2a8) at /test/b.cpp:37
if the init function init()
is invoked from a funcition pointer got by dlsym()
, the runtime will raise an error of segment fault
, but I cannot know which one is nullptr
. The only place I could check is the c++'s standard thread
header file, but I got no hint for why the runtime receives the nullptr
. I wonder if it's the static member initialization issue, but got no clue.
The full test code with a CMakeLists.txt could be find here
I've tested it with G++ 8.3.0, under Ubuntu OS.