boost::unit_test::output::compiler_log_formatter 中的 SIGSEGV 开始和结束
SIGSEGV in boost::unit_test::output::compiler_log_formatter start and finish
boost::unit_test::output::compiler_log_formatter::log_start() 调用 ostream::_M_insert()
中的 SIGSEGV
大家好!
我正在尝试编译使用 Boost.Test 模块的代码,并且在尝试使用某些参数时它似乎已经损坏:每当我 运行代码,在日志文件第一行的打印输出处。自定义命名的日志文件存在,但为空,并且没有发出错误消息。
我的设置是使用以下代码完成的,之后 BOOST_GLOBAL_FIXTURE 被初始化(成功)。如果我理解堆栈跟踪,错误似乎只在开始遍历 test_unit 树时发生。
我在 boost TRAC 上开了一张票:https://svn.boost.org/trac/boost/ticket/10943,但它甚至还没有被分配...
我是运行ning CentOS 6.5,所以我的boost版本是1.41
堆栈跟踪
Thread [1] 5624 [core: 6] (Suspended : Signal : SIGSEGV:Segmentation fault)
std::ostream::sentry::sentry() at 0x3495a915b1
std::ostream& std::ostream::_M_insert<unsigned long>() at 0x3495a95168
boost::unit_test::output::compiler_log_formatter::log_start() at compiler_log_formatter.ipp:50 0x45aaa3
boost::unit_test::unit_test_log_t::test_start() at unit_test_log.ipp:138 0x469ad5
boost::unit_test::ut_detail::test_start_caller::operator() at framework.ipp:71 0x489832
boost::unit_test::ut_detail::invoker<int>::invoke<boost::unit_test::ut_detail::test_start_caller>() at callback.hpp:42 0x4de998
boost::unit_test::ut_detail::callback0_impl_t<int, boost::unit_test::ut_detail::test_start_caller>::invoke() at callback.hpp:89 0x4db5a7
boost::unit_test::callback0<int>::operator() at callback.hpp:118 0x4a24ff
boost::detail::do_invoke<boost::scoped_ptr<boost::detail::translate_exception_base>, boost::unit_test::callback0<int> >() at execution_monitor.ipp:244 0x497784
boost::execution_monitor::catch_signals() at execution_monitor.ipp:841 0x461918
boost::execution_monitor::execute() at execution_monitor.ipp:1,167 0x4619dc
boost::unit_test::framework::run() at framework.ipp:418 0x45dc32
boost::unit_test::unit_test_main() at unit_test_main.ipp:185 0x46a85e
main() at unit_test_main.ipp:237 0x46aa58
调试信息
我猜 ostream 被优化了——我的 Eclipse GDB 给我的只是一个地址,这个地址可能很奇怪:
std::ostream & unit_test_log_t::test_start::s_log_impl().stream() = @0x7fffffffc9a0
取自第四个堆栈帧(作为参数传递给第三个帧)。
由 BOOST_GLOBAL_FIXTURE
加载
static const bool TestingDefs::formatBoostTestForJenkins = false;
/// Loaded by the BOOST_GLOBAL_FIXTURE
struct BoostTestFlags
{
BoostTestFlags() :
m_set(false)
{
Func_Reporter;
if (!m_set)
m_set = set();
}
bool set()
{
m_sOFStreamDirName = GlobalLoggerSingleton::instance()->getFullFilePath();
m_sOFStreamFileName = m_sOFStreamDirName + string("/") + string("BoostTests_") + to_iso_string(second_clock::local_time());
m_sOFStreamFileName += "."; ///< add filename extension according to filetype, TBD later on.
BETIS_LOGMSG((LM_INFO,"Boost.Test output will be written to %s",m_sOFStreamFileName.c_str()));
if (TestingDefs::formatBoostTestForJenkins)
{
m_sOFStreamFileName += "xml";
m_oFStreamBoostTests.open(m_sOFStreamFileName.c_str(), std::ofstream::out | std::ofstream::trunc);
if (!m_oFStreamBoostTests.is_open())
{
BETIS_LOGMSG((LM_ERROR,"BoostTestFlags::BoostTestFlags() Could not open output file stream for writing!"));
return false;
}
boost::unit_test::unit_test_log.set_stream(m_oFStreamBoostTests);
boost::unit_test::unit_test_log.set_format((boost::unit_test::output_format) XML); ///< --output_format=XML
boost::unit_test::unit_test_log.set_threshold_level((boost::unit_test::log_level) 0); ///< --log_level=all
boost::unit_test::results_reporter::set_level(boost::unit_test::report_level(NO_REPORT)); ///< --report_level=no
boost::unit_test::results_reporter::set_format((boost::unit_test::output_format) XML);
}
else ///< Flags for human readability, verbose
{
m_sOFStreamFileName += "log";
m_oFStreamBoostTests.open(m_sOFStreamFileName.c_str(), std::ofstream::out | std::ofstream::trunc);
if (!m_oFStreamBoostTests.is_open())
{
BETIS_LOGMSG((LM_ERROR,"BoostTestFlags::BoostTestFlags() Could not open output file stream for writing!"));
return false;
}
boost::unit_test::unit_test_log.set_stream(m_oFStreamBoostTests);
boost::unit_test::unit_test_log.set_format((boost::unit_test::output_format) CLF); ///< Compiler Log Format
boost::unit_test::unit_test_log.set_threshold_level((boost::unit_test::log_level) 0);
boost::unit_test::results_reporter::set_level(boost::unit_test::report_level(DETAILED_REPORT));
boost::unit_test::results_reporter::set_format((boost::unit_test::output_format) CLF);
cout.setf(ios_base::unitbuf); ///< Turn off STDOUT buffering to improve accuracy of communication between Boost.Test and Tests Runner (since Boost.Test does not provide a way to flush the stream). @warning This costs in execution time. @see github.com/xgsa/cdt-tests-runner/wiki/Features#known-problems
}
return true;
}
~BoostTestFlags()
{
Func_Reporter;
}
private:
ofstream m_oFStreamBoostTests;
string m_sOFStreamDirName;
string m_sOFStreamFileName;
bool m_set;
};
Epilog:仍然开放(截至 2 月 22 日)!
将一些 BOOST_TEST 宏移出 init_test_suite() 后,我现在在
中遇到分段错误
compiler_log_formatter::log_finish( std::ostream& ostr )
{
ostr.flush();
}
没有任何解释,在从每个 test_unit 获得打印输出后。摘要未打印到文件。
在没有得到任何帮助和一些绝望的摆弄之后,它似乎起作用了。我不确定如何。
原问题的可能原因:
- 无效的流对象(例如双开()等)。谢谢@sehe@.
- 从 BOOST_GLOBAL_FIXTURE 中调用 BOOST_TEST 宏,在 init_unit_test_suite() 中。
boost::unit_test::output::compiler_log_formatter::log_start() 调用 ostream::_M_insert()
中的 SIGSEGV大家好!
我正在尝试编译使用 Boost.Test 模块的代码,并且在尝试使用某些参数时它似乎已经损坏:每当我 运行代码,在日志文件第一行的打印输出处。自定义命名的日志文件存在,但为空,并且没有发出错误消息。
我的设置是使用以下代码完成的,之后 BOOST_GLOBAL_FIXTURE 被初始化(成功)。如果我理解堆栈跟踪,错误似乎只在开始遍历 test_unit 树时发生。
我在 boost TRAC 上开了一张票:https://svn.boost.org/trac/boost/ticket/10943,但它甚至还没有被分配...
我是运行ning CentOS 6.5,所以我的boost版本是1.41
堆栈跟踪
Thread [1] 5624 [core: 6] (Suspended : Signal : SIGSEGV:Segmentation fault)
std::ostream::sentry::sentry() at 0x3495a915b1
std::ostream& std::ostream::_M_insert<unsigned long>() at 0x3495a95168
boost::unit_test::output::compiler_log_formatter::log_start() at compiler_log_formatter.ipp:50 0x45aaa3
boost::unit_test::unit_test_log_t::test_start() at unit_test_log.ipp:138 0x469ad5
boost::unit_test::ut_detail::test_start_caller::operator() at framework.ipp:71 0x489832
boost::unit_test::ut_detail::invoker<int>::invoke<boost::unit_test::ut_detail::test_start_caller>() at callback.hpp:42 0x4de998
boost::unit_test::ut_detail::callback0_impl_t<int, boost::unit_test::ut_detail::test_start_caller>::invoke() at callback.hpp:89 0x4db5a7
boost::unit_test::callback0<int>::operator() at callback.hpp:118 0x4a24ff
boost::detail::do_invoke<boost::scoped_ptr<boost::detail::translate_exception_base>, boost::unit_test::callback0<int> >() at execution_monitor.ipp:244 0x497784
boost::execution_monitor::catch_signals() at execution_monitor.ipp:841 0x461918
boost::execution_monitor::execute() at execution_monitor.ipp:1,167 0x4619dc
boost::unit_test::framework::run() at framework.ipp:418 0x45dc32
boost::unit_test::unit_test_main() at unit_test_main.ipp:185 0x46a85e
main() at unit_test_main.ipp:237 0x46aa58
调试信息
我猜 ostream 被优化了——我的 Eclipse GDB 给我的只是一个地址,这个地址可能很奇怪:
std::ostream & unit_test_log_t::test_start::s_log_impl().stream() = @0x7fffffffc9a0
取自第四个堆栈帧(作为参数传递给第三个帧)。
由 BOOST_GLOBAL_FIXTURE
加载static const bool TestingDefs::formatBoostTestForJenkins = false;
/// Loaded by the BOOST_GLOBAL_FIXTURE
struct BoostTestFlags
{
BoostTestFlags() :
m_set(false)
{
Func_Reporter;
if (!m_set)
m_set = set();
}
bool set()
{
m_sOFStreamDirName = GlobalLoggerSingleton::instance()->getFullFilePath();
m_sOFStreamFileName = m_sOFStreamDirName + string("/") + string("BoostTests_") + to_iso_string(second_clock::local_time());
m_sOFStreamFileName += "."; ///< add filename extension according to filetype, TBD later on.
BETIS_LOGMSG((LM_INFO,"Boost.Test output will be written to %s",m_sOFStreamFileName.c_str()));
if (TestingDefs::formatBoostTestForJenkins)
{
m_sOFStreamFileName += "xml";
m_oFStreamBoostTests.open(m_sOFStreamFileName.c_str(), std::ofstream::out | std::ofstream::trunc);
if (!m_oFStreamBoostTests.is_open())
{
BETIS_LOGMSG((LM_ERROR,"BoostTestFlags::BoostTestFlags() Could not open output file stream for writing!"));
return false;
}
boost::unit_test::unit_test_log.set_stream(m_oFStreamBoostTests);
boost::unit_test::unit_test_log.set_format((boost::unit_test::output_format) XML); ///< --output_format=XML
boost::unit_test::unit_test_log.set_threshold_level((boost::unit_test::log_level) 0); ///< --log_level=all
boost::unit_test::results_reporter::set_level(boost::unit_test::report_level(NO_REPORT)); ///< --report_level=no
boost::unit_test::results_reporter::set_format((boost::unit_test::output_format) XML);
}
else ///< Flags for human readability, verbose
{
m_sOFStreamFileName += "log";
m_oFStreamBoostTests.open(m_sOFStreamFileName.c_str(), std::ofstream::out | std::ofstream::trunc);
if (!m_oFStreamBoostTests.is_open())
{
BETIS_LOGMSG((LM_ERROR,"BoostTestFlags::BoostTestFlags() Could not open output file stream for writing!"));
return false;
}
boost::unit_test::unit_test_log.set_stream(m_oFStreamBoostTests);
boost::unit_test::unit_test_log.set_format((boost::unit_test::output_format) CLF); ///< Compiler Log Format
boost::unit_test::unit_test_log.set_threshold_level((boost::unit_test::log_level) 0);
boost::unit_test::results_reporter::set_level(boost::unit_test::report_level(DETAILED_REPORT));
boost::unit_test::results_reporter::set_format((boost::unit_test::output_format) CLF);
cout.setf(ios_base::unitbuf); ///< Turn off STDOUT buffering to improve accuracy of communication between Boost.Test and Tests Runner (since Boost.Test does not provide a way to flush the stream). @warning This costs in execution time. @see github.com/xgsa/cdt-tests-runner/wiki/Features#known-problems
}
return true;
}
~BoostTestFlags()
{
Func_Reporter;
}
private:
ofstream m_oFStreamBoostTests;
string m_sOFStreamDirName;
string m_sOFStreamFileName;
bool m_set;
};
Epilog:仍然开放(截至 2 月 22 日)!
将一些 BOOST_TEST 宏移出 init_test_suite() 后,我现在在
中遇到分段错误compiler_log_formatter::log_finish( std::ostream& ostr )
{
ostr.flush();
}
没有任何解释,在从每个 test_unit 获得打印输出后。摘要未打印到文件。
在没有得到任何帮助和一些绝望的摆弄之后,它似乎起作用了。我不确定如何。
原问题的可能原因:
- 无效的流对象(例如双开()等)。谢谢@sehe@.
- 从 BOOST_GLOBAL_FIXTURE 中调用 BOOST_TEST 宏,在 init_unit_test_suite() 中。