2

我们的项目使用 Boost.Test 进行单元测试。当我们的测试用例发生意外异常时,我们也希望获得 minidump,因此我们已经开始集成 Google Breakpad 来编写 minidump。

看起来 Boost.Test 正在拦截用户测试中所有抛出的异常——我假设是因为 Boost 测试用例用 try / catch 包装了每个函数,如果抛出意外异常,单元测试就会失败。这可以防止 Breakpad 异常处理程序触发和写入小型转储。

是否有可能让 Boost.Test 不仅在单元测试中捕获和失败意外异常?而是让异常未经处理(或重新抛出),以便可以触发 Breakpad 或其他异常处理程序来编写小型转储?

4

2 回答 2

1

我尝试了几种不同的方法,但以下解决方案提供了最佳结果。定义一个宏来包装 BOOST_AUTO_TEST_CASE 宏,并用 SEH __try/__except 包围调用代码,并将异常数据通过管道传输到 Breakpad。

#define CUSTOM_AUTO_TEST_CASE( test_name )                                                                  \
void test_name##_custom_wrapper();                                                                          \
                                                                                                            \
BOOST_AUTO_TEST_CASE( test_name )                                                                           \
{                                                                                                           \
    __try                                                                                                   \
    {                                                                                                       \
        test_name##_custom_wrapper();                                                                       \
    }                                                                                                       \
    __except(pHandler->WriteMinidumpForException(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER) {}  \
}                                                                                                           \
                                                                                                            \
void test_name##_custom_wrapper()                                                                           \

其中 pHandler 是 Breakpad ExceptionHandler 指针。

缺点是您必须用包装宏替换每次出现的 BOOST_AUTO_TEST_CAST。但它确实有效。

于 2017-10-06T00:06:15.413 回答
1

Boost.Test 旨在捕获测试用例中的所有异常,以便继续执行其他测试用例。我认为您无法关闭此行为,但您可以随时查阅源代码。

为了实现您所追求的目标,我会自己包装测试用例的主体并捕获异常,并在抛出意外异常时写出 breakpad minidumps。您可以通过将 catch/dump 处理程序编写为接受作为测试用例主体的函子并在 lambda 中使用测试用例主体调用处理程序的函数来通用化:

void handler(std::function<void()> test_case)
{
  try {
    test_case();
  } catch (...) {
    write_minidump();
  }
}

BOOST_AUTO_TEST_CASE(doit)
{
  handler([] {
    // do testing here
  });
}

如果您使用的是固定装置,它会涉及更多,但同样的想法也适用。

于 2017-10-04T16:50:18.870 回答