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
相关产品推荐
相关产品推荐

