You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

两个独立.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.16 06:54:38