两个独立.so文件共用spdlog导致段错误的排查求助
两个独立.so文件共用spdlog导致段错误的排查求助
我最近碰到个头疼的问题:我的可执行程序需要加载两个.so库文件,但不管调整加载顺序,第二个.so加载时一定会触发段错误。而且我是链接了共享版本的spdlog日志库的。
我试过写最小复现案例来重现这个问题,但一直没能成功复现。不过我还是把这个最小案例的代码贴出来,希望有大佬能给我一些排查思路或者提示,帮我找找问题可能出在哪。
log_wrap.hpp
#ifndef LOG_WRAP_HPP #define LOG_WRAP_HPP #include <spdlog/spdlog.h> #include <spdlog/sinks/stdout_color_sinks.h> #include <cxxabi.h> #include <mutex> #include <vector> #include <atomic> #include <memory> class LogImpl; class LogRegister { inline static std::vector<spdlog::sink_ptr> sinks; inline static std::mutex mmutex; inline static std::atomic<bool> sss{ false }; template <typename SINK, typename... ARGS> static void add_sink(std::atomic<bool>& state, ARGS... args) { const std::lock_guard<std::mutex> lock(mmutex); if (!state.load(std::memory_order_acquire)) { sinks.emplace_back(std::make_shared<SINK>(args...)); state.store(true, std::memory_order_release); } } public: static void init() { add_sink<spdlog::sinks::stdout_color_sink_mt>(sss); spdlog::set_default_logger(std::make_shared<spdlog::logger>("default", begin(sinks), end(sinks))); spdlog::set_level(spdlog::level::trace); } }; #endif // LOG_WRAP_HPP
一些我想到的排查方向(也欢迎补充)
- 检查两个.so库是不是各自链接了spdlog的静态版本?如果是这样的话,会导致spdlog的全局对象被重复初始化,很可能引发内存冲突
- 确认spdlog的全局状态(比如默认logger、sinks集合)在两个.so中有没有出现重复初始化或者并发访问竞争的情况
- 用
gdb挂上可执行程序,触发段错误后查看栈回溯,定位到具体的崩溃代码行,看看是spdlog内部的哪个操作出了问题 - 核对两个.so库的编译选项是否一致:比如C++标准版本、编译优化等级,或者是否开启了不同的spdlog编译宏(比如
SPDLOG_FMT_EXTERNAL这类) - 试试把spdlog改为静态链接到主可执行程序,而不是让两个.so各自链接,看能不能解决问题
备注:内容来源于stack exchange,提问作者ATK
相关产品推荐
相关产品推荐

