[Boost-users] Boostlog and ASIO crash in shared library

118 views
Skip to first unread message

Ray Cheng

unread,
Sep 16, 2014, 9:28:21 AM9/16/14
to boost...@lists.boost.org
Hi, 

My project use a simple main using dlopen to "run" the real main function in target shared library. I use both Boost Log and ASIO (for threadpool) in the project. In Linux I found the ASIO got weird behavior with some un-initialized variables and crashing all the time. I am able to trim down my problem into a small program as below: 

// *** threadpool.cpp ***
#include <iostream> 
#include <memory> 
#include <boost/asio/io_service.hpp> 
#include <boost/bind.hpp> 
#include <boost/thread/thread.hpp> 

void print() { 
    std::cout << "print" << std::endl; 

struct ThreadPool 
    void start() 
    { 
        boost::asio::io_service ioService; 
        boost::thread_group threadpool; 
        std::unique_ptr<boost::asio::io_service::work> work = std::make_unique<boost::asio::io_service::work>(ioService); 
        threadpool.create_thread(boost::bind(&boost::asio::io_service::run, &ioService)); 

        for (int i=0; i<100; ++i) 
        { 
            ioService.post(&print); 
        } 
        std::cout << "Post all calculation tasks" << std::endl; 

        work.reset(); 
        threadpool.join_all(); 
        ioService.stop(); 
        std::cout  << "Finished all calculation tasks" << std::endl; 
    } 
}; 

extern "C" void createthreadpool() 
    ThreadPool pool; 
    pool.start(); 
// *** threadpool.cpp *** 

g++ -O0 -std=gnu++1y -fPIC -c -g -DLinux -DGNU_GCC -I${BOOST_HOME}/include threadpool.cpp 
g++ -shared -o libthreadpool.so threadpool.o -L${BOOST_HOME}/lib -lboost_system -lboost_date_time -lboost_thread -lboost_filesystem -lboost_regex -lboost_chrono -ldl -lstdc++ 

// *** main.cpp ***
#include <dlfcn.h> 
#include <iostream> 

int main(int argc, char** argv) { 
    typedef void* createProcess(); 
    auto service = dlopen("libthreadpool.so", RTLD_LAZY); 

    createProcess* make = reinterpret_cast<createProcess*>(dlsym(service, "createthreadpool")); 
    std::cout << "dlsym" << std::endl; 
    make(); 
    return 0; 
// *** main.cpp ***

g++ -O0 -std=gnu++1y -fPIC -c -g -DLinux -DGNU_GCC main.cpp 
// Link against boost_log to simulate my problem (although it is not using any boost_log). This version will crash 
g++ -o main.bad main.o -L${BOOST_HOME}/lib -lboost_system -lboost_date_time -lboost_thread -lboost_filesystem -lboost_regex -lboost_chrono -lboost_log -ldl -lstdc++ 
// it works fine If link against libthreadpool, surprising me 
g++ -o main main.o -L/home/sysmmbuild/dev/boost -lthreadpool -L${BOOST_HOME}/lib -lboost_system -lboost_date_time -lboost_thread -lboost_filesystem -lboost_regex -lboost_chrono -lboost_log -ldl -lstdc++ 

One more finding is, if compile boost_log without thread support, the main.bad also working fine. 

I have attached the code and make.sh as make script. 

Software version 
Redhat enterprise 6.5 
g++ 4.9.1 
Boost 1.56.0 

Rgds,
Ray

main.cpp
make.sh
threadpool.cpp

Sohail Somani

unread,
Sep 16, 2014, 10:48:41 PM9/16/14
to boost...@lists.boost.org
On 2014-09-16, 3:08 AM, Ray Cheng wrote:
> My project use a simple main using dlopen to "run" the real main
> function in target shared library. I use both Boost Log and ASIO (for
> threadpool) in the project. In Linux I found the ASIO got weird behavior
> with some un-initialized variables and crashing all the time. I am able
> to trim down my problem into a small program as below:

There might be some interaction with BOOST_LOG_USE_COMPILER_TLS from the
sounds of it. Try disabling/enabling that and see if that narrows it
down further.

It does look like you're doing the right thing, but ensure that your
shared object will invoke global C++ constructors. I remember some *nix
somewhere at some time that didn't do this.

Sohail


_______________________________________________
Boost-users mailing list
Boost...@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users

Ray Cheng

unread,
Sep 16, 2014, 11:12:56 PM9/16/14
to boost...@lists.boost.org
On Wed, Sep 17, 2014 at 10:48 AM, Sohail Somani <soh...@taggedtype.net> wrote:
There might be some interaction with BOOST_LOG_USE_COMPILER_TLS from the sounds of it. Try disabling/enabling that and see if that narrows it down further.

It does look like you're doing the right thing, but ensure that your shared object will invoke global C++ constructors. I remember some *nix somewhere at some time that didn't do this.

I did try explicitly undef BOOST_LOG_USE_COMPILER_TLS in boost/config/user.hpp, but it didn't help. I did a global search BOOST_LOG_USE_COMPILER_TLS is by default disable, no where define it in boost code.

What is the "global C++ constructors"? may be i missed something when using boost_log?
Reply all
Reply to author
Forward
0 new messages