【问题标题】:How to run Boost Test and produce Minidumps?如何运行 Boost 测试并生成 Minidump?
【发布时间】:2018-03-15 07:17:54
【问题描述】:

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

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

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

【问题讨论】:

    标签: c++ unit-testing boost boost-test google-breakpad


    【解决方案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
      });
    }
    

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

    【讨论】:

    • 我喜欢这个建议,但是当 minidump 被写入 catch 块时,保存在 minidump 中的调用堆栈只会在堆栈顶部显示“处理程序”。但是,当触发“未处理的异常过滤器”并写入转储时,会保留有问题的调用堆栈。
    • breakpad 如何设置异常处理程序?
    • chromium.googlesource.com/breakpad/breakpad/+/master/docs/… 我已经根据那里的文档创建了一个 ExceptionHandler 。只需这个 Breakpad 设置它自己的未处理异常过滤器回调,未处理异常就可以很好地生成小型转储。但是,我在类似于您发布的内容的 catch 块中明确使用了“WriteMinidump”API。
    • 是的,如果您编写一个在catch 处捕获的小型转储,那么您的堆栈中将只有handler。不知何故,您需要在抛出异常时捕获调用堆栈。我不确定breakpad是如何做到的。我知道在 Windows SEH 中,您可以从 catch 处理程序中查询此信息。
    【解决方案2】:

    我尝试了几种不同的方法,但以下解决方案提供了最佳结果。定义一个宏来包装 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。但它确实有效。

    【讨论】:

      猜你喜欢
      • 2021-01-30
      • 2013-06-24
      • 1970-01-01
      • 2011-07-31
      • 1970-01-01
      • 2011-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多