首页 > 解决方案 > 如何在预编译后通过查看文件来调试 Boost?

问题描述

在定义一个带有 boost 的测试套件时,我遇到了一个非常奇怪的错误:

BOOST_AUTO_TEST_SUITE(zerocoin_implementation_tests)

错误如下所示:

terminate called after throwing an instance of 'std::length_error'
  what():  basic_string::_M_create

这是相关的回溯:

#5  0x00007ffff5ce6fe8 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x00007ffff5ce2875 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7  0x00007ffff5d7c949 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_create(unsigned long&, unsigned long) ()
   from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#8  0x00007ffff70afe15 in boost::unit_test::test_unit::test_unit(boost::unit_test::basic_cstring<char const>, boost::unit_test::basic_cstring<char const>, unsigned long, boost::unit_test::test_unit_type) () from /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.so.1.65.1
#9  0x00007ffff70b0456 in boost::unit_test::test_suite::test_suite(boost::unit_test::basic_cstring<char const>, boost::unit_test::basic_cstring<char const>, unsigned long) () from /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.so.1.65.1
#10 0x00007ffff70b0612 in boost::unit_test::ut_detail::auto_test_unit_registrar::auto_test_unit_registrar(boost::unit_test::basic_cstring<char const>, boost::unit_test::basic_cstring<char const>, unsigned long, boost::unit_test::decorator::collector&) ()
   from /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.so.1.65.1

据我所知,这与 Boost 试图创建最大长度字符串有关。我想看看它到底在做什么。扩展 boost 宏以查看预编译版本的最佳方法是什么?


边注

奇怪的是,如果我将这一行稍微更改为:

BOOST_AUTO_TEST_SUITE(zerocsoin_implementation_tests)

我收到以下错误:

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

和回溯:

#6  0x00007ffff5ce7594 in operator new(unsigned long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7  0x00007ffff70afe15 in boost::unit_test::test_unit::test_unit(boost::unit_test::basic_cstring<char const>, boost::unit_test::basic_cstring<char const>, unsigned long, boost::unit_test::test_unit_type) () from /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.so.1.65.1
#8  0x00007ffff70b0456 in boost::unit_test::test_suite::test_suite(boost::unit_test::basic_cstring<char const>, boost::unit_test::basic_cstring<char const>, unsigned long) () from /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.so.1.65.1
#9  0x00007ffff70b0612 in boost::unit_test::ut_detail::auto_test_unit_registrar::auto_test_unit_registrar(boost::unit_test::basic_cstring<char const>, boost::unit_test::basic_cstring<char const>, unsigned long, boost::unit_test::decorator::collector&) ()
   from /usr/lib/x86_64-linux-gnu/libboost_unit_test_framework.so.1.65.1

该文件(以及项目的其余部分)的源代码可以在这里找到:https ://github.com/phoreproject/Phore/blob/segwit/src/test/zerocoin_implementation_tests.cpp

可能导致错误的差异:https ://github.com/phoreproject/phore/compare/master...segwit#diff-bb4f094cc636d668944ed6af9b72c0d9

标签: c++linuxboost

解决方案


两种方法:

异常断点

只需在调试器中启动测试并捕获异常。

在 gdb 你可以做

(gdb) catch throw 
Catchpoint 2 (throw)

这就像一个通用断点。Visual Studio 有一个“管理例外”对话框。¹

提升测试断点

对于调试 Boost Test,我喜欢在test_method我想中断的特定测试用例类的成员处设置中断。例如,带有一些嵌套套件的 test_runner,例如:

./test_runner --list_content
import*
    utility*
        xml*
            xml_utilities*
            child_text_test*
            loggable_xml_path_test*

我们运行这 3 个测试,例如:

./test_runner -t import/utility/xml
Running 3 test cases...

*** No errors detected

要使用 gdb 调试它们,我会这样做

gdb ./test_runner 
start -t import/utility/xml

停在main,然后我输入:

break import::utility::xml

自动完成有帮助,因此要获得确切的名称,您可以从完成中选择:

xml
xml::as_element(xmlpp::Node const&)
xml::attr_value(xmlpp::Element const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
xml::attr_value(xmlpp::Node const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
xml::child_text[abi:cxx11](xmlpp::Element const&, char const*)
xml::child_text_test
xml::child_text_test::test_method()
xml::child_text_test_invoker()
xml::child_text_test_registrar62
xml::end_suite94_registrar94
xml::first_child(xmlpp::Element const&, char const*)
xml::get_content[abi:cxx11](xmlpp::Element const&)
xml::get_content[abi:cxx11](xmlpp::Node const*)
xml::is_attr_value(xmlpp::Node const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
xml::loggable_xml_path[abi:cxx11](xmlpp::Node const&)
xml::loggable_xml_path_test
xml::loggable_xml_path_test::test_method()
xml::loggable_xml_path_test_invoker()
xml::loggable_xml_path_test_registrar77
xml::trace_xml(xmlpp::Element const&, LogSource::LogTx)
xml::trace_xml_formatted(xmlpp::Element const&, LogSource::LogTx)
xml::xml_registrar20
xml::xml_utilities
xml::xml_utilities::test_method()
xml::xml_utilities_invoker()
xml::xml_utilities_registrar22

选择那些命名的test_method(),例如

break import::utility::xml::child_text_test::test_method() 
Breakpoint 2 at 0x730762: file /path/src/import/utility/xml_tests.cpp, line 62.

现在您可以continue执行,调试器将在单元测试开始时自动暂停执行。


¹ 参见


推荐阅读