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

在Google Test中使用boost::log触发访问违规的解决咨询

Boost.Log集成Google Test时Windows下触发访问违规问题

问题描述

单独运行以下Boost.Log代码时,控制台可正常输出"Test Log":

#include <boost/log/trivial.hpp>
#include <boost/log/sources/severity_logger.hpp>

int main()
{
  boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level> logger;
  BOOST_LOG_SEV(logger, boost::log::trivial::info) << "Test Log";

  return 0;
}

按逻辑,即使未配置任何sink,Boost.Log默认会将日志输出到控制台,因此代码可正常运行。

但将该代码集成到同解决方案下的Google Test项目时,触发访问违规,测试无法通过,报错信息为:
unknown file: error: SEH exception with code 0xc0000005 thrown in the test body

测试代码如下:

#include "pch.h"
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/trivial.hpp>

TEST(TestCaseName, TestName) {
  EXPECT_EQ(1, 1);
  EXPECT_TRUE(true);
}

TEST(TestCaseName, LogTest1) {
  boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level> logger;
  BOOST_LOG_SEV(logger, boost::log::trivial::info) << "Test Log";

  EXPECT_TRUE(true);
}

开发环境

  • C++17
  • Visual Studio 2022 专业版
  • Google Test
  • 通过vcpkg安装的Boost 1.80(boost-log:x64-windows, 1.80.0#1)

已尝试方案

  • 配置虚拟sink,无效
  • 创建severity logger的空子类(可行但因Boost模板特性难以多态传递)

调试补充信息

调试时程序在memmove函数处中断,路径为C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.37.32822\include\xstring第119行,报错信息:

Exception thrown at 0x00007FFD88A01441 (vcruntime140d.dll) in Sample-Test1.exe: 0xC0000005: Access violation writing location 0x000000000000000F.

堆栈跟踪:

vcruntime140d.dll!00007ffd88a01441()    Unknown
Sample-Test1.exe!std::_Char_traits<char,int>::move(char * const _First1, const char * const _First2, const unsigned __int64 _Count) Line 122    C++
Sample-Test1.exe!std::string::append(const char * const _Ptr, const unsigned __int64 _Count) Line 3276  C++
Sample-Test1.exe!boost::log::v2_mt_nt6::aux::basic_ostringstreambuf<char,std::char_traits<char>,std::allocator<char>>::append(const char * s, unsigned __int64 n) Line 185  C++
Sample-Test1.exe!boost::log::v2_mt_nt6::basic_formatting_ostream<char,std::char_traits<char>,std::allocator<char>>::formatted_write(const char * p, __int64 size) Line 737  C++
Sample-Test1.exe!boost::log::v2_mt_nt6::basic_formatting_ostream<char,std::char_traits<char>,std::allocator<char>>::operator<<(const char * p) Line 441 C++
Sample-Test1.exe!boost::log::v2_mt_nt6::basic_record_ostream<char>::operator<<(const char * p) Line 219 C++
Sample-Test1.exe!TestCaseName_LogTest1_Test::TestBody() Line 12 C++
Sample-Test1.exe!testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test,void>(testing::Test * object, void(testing::Test::*)() method, const char * location) Line 2428    C++
Sample-Test1.exe!testing::internal::HandleExceptionsInMethodIfSupported<testing::Test,void>(testing::Test * object, void(testing::Test::*)() method, const char * location) Line 2479   C++
Sample-Test1.exe!testing::Test::Run() Line 2524 C++
Sample-Test1.exe!testing::TestInfo::Run() Line 2697 C++
Sample-Test1.exe!testing::TestCase::Run() Line 2812 C++
Sample-Test1.exe!testing::internal::UnitTestImpl::RunAllTests() Line 5178   C++
Sample-Test1.exe!testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl,bool>(testing::internal::UnitTestImpl * object, bool(testing::internal::UnitTestImpl::*)() method, const char * location) Line 2428  C++
Sample-Test1.exe!testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl,bool>(testing::internal::UnitTestImpl * object, bool(testing::internal::UnitTestImpl::*)() method, const char * location) Line 2479 C++
Sample-Test1.exe!testing::UnitTest::Run() Line 4786 C++
Sample-Test1.exe!RUN_ALL_TESTS() Line 2342  C++
Sample-Test1.exe!main(int argc, char * * argv) Line 37  C++
Sample-Test1.exe!invoke_main() Line 79  C++
Sample-Test1.exe!__scrt_common_main_seh() Line 288  C++
Sample-Test1.exe!__scrt_common_main() Line 331  C++
Sample-Test1.exe!mainCRTStartup(void * __formal) Line 17    C++
kernel32.dll!00007ffda1727344() Unknown
ntdll.dll!00007ffda25626b1()    Unknown

补充说明

2024年12月更新:在Ubuntu 2024环境下未复现该问题,推测为Windows特定问题。


解决方案

该问题源于Windows下Boost.Log与Google Test的全局对象初始化顺序冲突——Boost.Log默认控制台sink依赖的全局对象,在Google Test框架初始化前未完成构造,或在测试执行期间被提前销毁,进而引发非法内存访问。可通过以下方式解决:

1. 显式初始化Boost.Log核心

在所有测试执行前,显式初始化Boost.Log的核心组件,避免依赖默认延迟初始化。可通过Google Test的全局环境钩子实现:

#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/sinks/text_ostream_backend.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <gtest/gtest.h>

class LogInitializer : public testing::Environment {
public:
    void SetUp() override {
        // 初始化Boost.Log核心并配置控制台sink
        auto core = boost::log::core::get();
        core->set_filter(boost::log::trivial::severity >= boost::log::trivial::info);
        boost::log::add_console_log(std::cout);
        boost::log::add_common_attributes();
    }
};

int main(int argc, char** argv) {
    testing::InitGoogleTest(&argc, argv);
    // 注册全局初始化器
    testing::AddGlobalTestEnvironment(new LogInitializer);
    return RUN_ALL_TESTS();
}

2. 临时禁用Boost.Log输出

如果测试不需要日志输出,可临时禁用所有sink避免初始化问题:

#include <boost/log/core.hpp>
#include <boost/log/expressions.hpp>
#include <gtest/gtest.h>

TEST(TestCaseName, LogTest1) {
    auto core = boost::log::core::get();
    // 保存原有过滤规则
    auto original_filter = core->get_filter();
    // 禁用所有日志输出
    core->set_filter(boost::log::expressions::false_val());
    
    boost::log::sources::severity_logger_mt<boost::log::trivial::severity_level> logger;
    BOOST_LOG_SEV(logger, boost::log::trivial::info) << "Test Log";
    
    // 恢复原有过滤规则(可选)
    core->set_filter(original_filter);
    EXPECT_TRUE(true);
}

3. 调整MSVC链接顺序

在Visual Studio中,将boost-log库的链接顺序调整到gtest/gtest_main之前,确保Boost.Log全局对象优先构造:

  • 右键测试项目 → 属性 → 链接器 → 输入 → 附加依赖项,将boost-log-vc143-mt-gd-x64-1_80.lib(对应你的Boost版本)移到gtestd.lib、gtest_maind.lib之前。

4. 升级Boost版本

该问题在Boost 1.81及以后版本中已被修复,直接升级到最新稳定版即可解决冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 09:25:55