0

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.

hsinchao
  • 43
  • 2
  • 1
    Can't reproduce (Suse Linux + g++ 9.2.1). Are you sure the library is found? Your error handling simply prints a message and continues regardless. – G.M. Apr 09 '20 at 10:48
  • you may set up the build directly inner the folder, since it would check the `liba.so` under the current working directory. To build it, just use "cmake .". If you build in a differnt directory, you can create a soft link for the `liba.so` unnder the binary `b`. `b` should find the `liba.so` just under the same folder. – hsinchao Apr 09 '20 at 11:35
  • When I say `"Can't reproduce"` I mean I can't reproduce the problem. It builds and works as expected. – G.M. Apr 09 '20 at 11:37
  • Yes. Seems it's GCC bug. I've tested GCC with version 7.4.0 and 8.4.0 on ubuntu, and the segment fault could be reproduced. After changing to clang-9, it could work normally. GCC 9 is too newer for me to get one. I'd like to find the root reason and check if there is way work around this bug. – hsinchao Apr 10 '20 at 01:01
  • It's a known problem of libstdc++, which is found https://stackoverflow.com/questions/51209268/using-stdthread-in-a-library-loaded-with-dlopen-leads-to-a-sigsev . Who can help me close this question?? – hsinchao Apr 10 '20 at 01:23

0 Answers0