c++ - 使用 Boost.Log 和 Boost.ASIO 导致崩溃

标签 c++ c++11 boost boost-asio boost-log

我遇到一个问题,当应用程序加载使用 Boost.ASIO 的共享库时,在应用程序中使用 Boost.Log 会导致崩溃或挂起!任何见解将不胜感激;下面是一个完整的 cmake-buildable 示例。

如果在 main.cpp 中全局记录器对象的声明被取消注释,程序将立即出现段错误,或者 resolve() 调用将不执行任何操作。如果留下注释,则程序可以运行。

我正在使用 Boost 1.55,g++ (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4

CMakeLists.txt

cmake_minimum_required (VERSION 2.8)
project (boosttest)
add_definitions(-fPIC -pthread -std=c++11)
find_package(Boost 1.55.0 REQUIRED)
add_definitions( -DBOOST_LOG_DYN_LINK )
include_directories(${Boost_INCLUDE_DIRS})

# Build the shared lib.
add_library(testlib SHARED
    Lib
)

target_link_libraries(testlib
    pthread
)

# Build the test app.
add_executable(testapp
    main
)

target_link_libraries(testapp
    dl
    pthread
    boost_system
    boost_log
)

main.cpp

#include <iostream>
#include <memory>
#include <dlfcn.h>
#include <boost/log/core.hpp>
#include <boost/log/sources/channel_logger.hpp>

#include "Lib.h"

using LoggerType = boost::log::sources::channel_logger_mt<>;
//LoggerType gLogger; // If this is uncommented then probably a crash.


std::unique_ptr<Lib> LoadLib(const std::string& libName) {
    typedef Lib* (*LibConstructor)();

    union FunctionLookup {
        LibConstructor entry;
        void* voidPtr;
    };

    void* handle = ::dlopen(libName.c_str(), RTLD_LAZY);
    if (!handle) {
        throw std::runtime_error(::dlerror());
    }

    FunctionLookup lookup;

    lookup.voidPtr = ::dlsym(handle, "create");
    if (!lookup.voidPtr) {
        throw std::runtime_error(::dlerror());
    }

    return std::unique_ptr<Lib>(lookup.entry());
}


int main(int argc, char* argv[]) {
    try {
        std::unique_ptr<Lib> lib = LoadLib("./libtestlib.so");
        std::cout << "successfully loaded lib\n";
        lib->resolve("www.google.com");
    }
    catch (const std::exception& e) {
        std::cerr << "*** " << e.what() << "\n";
    }

   std::cout << "Exiting" << std::endl;
   return 0;
}

库.h

#pragma once
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

class Lib
{
public:
    Lib();
    virtual ~Lib() {}
    virtual void resolve(const std::string& host);

private:
    void onResolve(const boost::system::error_code&, tcp::resolver::iterator);

    boost::asio::io_service m_ioService;
    tcp::resolver m_resolver;
};

库.cpp

#include <functional>
#include "Lib.h"

extern "C" Lib* create() { return new Lib(); }
extern "C" void destroy(Lib* lib) { delete lib; }

Lib::Lib()
:  m_resolver(m_ioService)
{
}

void Lib::resolve(const std::string& host) {
    tcp::resolver::query query(host, "http");
    auto next = std::bind(&Lib::onResolve, this, std::placeholders::_1, std::placeholders::_2);
    m_resolver.async_resolve(query, std::move(next));
    m_ioService.run(); // If it doesn't crash then this does nothing.
}


void Lib::onResolve(const boost::system::error_code& /*err*/, tcp::resolver::iterator /*iter*/)
{
    std::cout << "onResolve() called!\n";
}

最佳答案

所以我设法通过不动态链接 Boost.Log 库来解决这个问题(我认为)。

新建 CMakeLists.txt

cmake_minimum_required (VERSION 2.8)
project (boosttest)
add_definitions(-fPIC -pthread -std=c++11)
find_package(Boost 1.55.0 REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})

# Build the shared lib.
add_library(testlib SHARED
    Lib
)

target_link_libraries(testlib
    pthread
)

# Build the test app.
add_executable(testapp
    main
)

target_link_libraries(testapp
    dl
    pthread
    boost_system
    boost_log.a
    boost_thread
)

关于c++ - 使用 Boost.Log 和 Boost.ASIO 导致崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39948997/

相关文章:

c++ - 如何将 dynamic_cast 与 for_each 一起使用

c++ - std::tr1::mem_fn 返回类型

c++ - 循环遍历struct元素

multithreading - 在32位MinGW 4.8.0中使用g++时std::thread出现问题

C++11:函数模板:通过引用传递参数

c++ - 澄清 `boost::bind`和 `this`的使用

c++ - 自己的 AddRef 和 Release for Boost shared_ptr

c++ - 为什么此宏没有扩展?

c++ - 是否可以将 C++0x lambda 转换为 clang block ?

c++ - 在内存映射文件中存储 vector