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

Qt应用调用spdlog记录日志时崩溃问题求助

Qt中spdlog调用崩溃的排查与解决

针对你遇到的init函数内日志正常输出、main函数中调用日志接口崩溃的问题,以下是几个实用的排查方向和解决方案:

1. 优先确保日志目录存在

spdlog的rotating_file_sink_mt不会自动创建上级目录,如果logs/目录不存在,sink会处于无效状态——部分场景下异常可能被内部处理,导致init中无报错,但后续调用日志接口时直接崩溃。

修改init函数,先创建日志目录:

void init()
{
    try
    {
        // 确保日志目录存在,不存在则创建
        QDir logDir("logs");
        if (!logDir.exists()) {
            if (!logDir.mkpath(".")) {
                throw std::runtime_error("Failed to create log directory");
            }
        }

        auto sharedFileSink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(filename, max_file_size, max_files, false);
        auto guilogger = std::make_shared<spdlog::logger>("GUI", sharedFileSink);
        spdlog::register_logger(guilogger);
        spdlog::set_default_logger(spdlog::get("GUI"));
        spdlog::get("GUI")->info("Selftest after register OK");
    }
    catch (const spdlog::spdlog_ex& ex)
    {
        std::cout << "Log initialization failed: " << ex.what() << std::endl;
    }
    catch (const std::exception& ex)
    {
        std::cout << "Error: " << ex.what() << std::endl;
    }
}

2. 强制校验Logger指针有效性

虽然你打印了"got logger",但spdlog::get("GUI")仍可能返回空指针(比如注册时出现隐性错误),此时调用info会直接崩溃。在main函数中添加指针校验:

auto logger = spdlog::get("GUI"); 
if (!logger) {
    std::cout << "Failed to retrieve GUI logger!\n";
    return 1;
}
std::cout<< "got logger";
logger->info("test123");

3. 统一编译选项避免链接冲突

这是Qt搭配第三方库常见的崩溃诱因:

  • 确保spdlog和Qt项目使用相同的CRT链接方式(比如都用MT静态库,或都用MD动态库)
  • 统一C标准版本(spdlog较新版本依赖C17特性,需和Qt项目设置一致)
  • 如果是源码编译spdlog,确保定义了SPDLOG_COMPILED_LIB宏(与Qt项目的宏定义保持一致)

4. 排查异步日志的线程池初始化

你包含了spdlog/async.h但未初始化异步线程池,如果代码隐性触发了异步模式,会导致崩溃:

  • 若不需要异步日志,直接移除spdlog/async.h的包含;
  • 若需要异步日志,先初始化线程池再创建logger:
void init()
{
    try
    {
        // 初始化异步日志线程池(队列大小8192,1个工作线程)
        spdlog::init_thread_pool(8192, 1);
        
        QDir logDir("logs");
        if (!logDir.exists()) {
            logDir.mkpath(".");
        }

        auto sharedFileSink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(filename, max_file_size, max_files, false);
        // 创建异步logger
        auto guilogger = std::make_shared<spdlog::async_logger>("GUI", sharedFileSink, spdlog::thread_pool(), spdlog::async_overflow_policy::block);
        spdlog::register_logger(guilogger);
        spdlog::set_default_logger(spdlog::get("GUI"));
        spdlog::get("GUI")->info("Selftest after register OK");
    }
    catch (const spdlog::spdlog_ex& ex)
    {
        std::cout << "Log initialization failed: " << ex.what() << std::endl;
    }
}

内容的提问来源于stack exchange,提问作者Tiny_Pointer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 16:11:08