1

刚开始使用 boost 测试框架。使用 Ubuntu + gcc(如果重要,可以通过新事物在 Windows 上运行)。当我运行测试时,我得到了这个:

unknown location(0): fatal error: in "PhraseListTest/everythingEqual8": signal: SIGSEGV, si_code: 0 (memory access violation at address: 0x00000080)
/mnt/c/projects/matching/matching-native/src/test/cpp/phrase_list_test.cpp(70): last checkpoint

*** 1 failure is detected in the test module "burningmime_matching_tests"

我将如何找到我的代码中发生的位置?消息给出的唯一指示指向测试中的一行。有问题的行只是:

BOOST_CHECK(matches(phraseList, bitset));

我相当确定问题发生在matches()函数内部的某个地方(可能有很多层次),但是......在哪里?


如果有人正在阅读本文,则“重复”答案都不起作用;显然人们在没有考虑上下文的​​情况下关闭了它。

Boost Test Framework 将信号处理程序替换为自己的(并在执行每个测试之前完成)。这意味着在每个测试开始时,您需要替换信号处理程序。我最终得到了这样的东西......

一些标题:

struct SignalToStacktraceScope
{
    SignalToStacktraceScope();
    ~SignalToStacktraceScope();
};

一些源文件:

#include <cstdio>
#include <csignal>
#include <iostream>
#include <boost/stacktrace.hpp>

    #if !NDEBUG && !BOOST_OS_WINDOWS
        typedef void (*FSignalHandler)(int signum);
        static void stacktraceHandler(int signum, const char* signame, FSignalHandler oldHandler)
        {
            fprintf(stderr, "\n\n===========================================\nReceived signal %s\n", signame);
            fflush(stderr); // flush before stack trace in case getting the stack trace itself produces another segfault
            std::cerr << boost::stacktrace::stacktrace();
            fprintf(stderr, "===========================================\n\n");
            fflush(stderr);

            // then raise the signal again to go back to the test framework
            signal(signum, oldHandler);
            raise(signum);
        }

        #define FOREACH_SIGNAL(F) \
            F(SIGSEGV) \
            F(SIGFPE) \
            F(SIGABRT) \
            F(SIGTERM)

        #define DEFINE_SIGNAL_WRAPPER(S) \
            static FSignalHandler oldHandler_##S = nullptr; \
            static void stacktraceHandler_##S(int signum) \
            { \
                stacktraceHandler(signum, #S, oldHandler_##S); \
            }
        FOREACH_SIGNAL(DEFINE_SIGNAL_WRAPPER)
        #undef DEFINE_SIGNAL_WRAPPER

        SignalToStacktraceScope::SignalToStacktraceScope()
        {
            #define HOOK_SIGNAL_WRAPPER(S) oldHandler_##S = signal(S, &stacktraceHandler_##S);
            FOREACH_SIGNAL(HOOK_SIGNAL_WRAPPER)
            #undef HOOK_SIGNAL_WRAPPER
        }

        SignalToStacktraceScope::~SignalToStacktraceScope()
        {
            #define UNHOOK_SIGNAL_WRAPPER(S) { signal(S, oldHandler_##S); oldHandler_##S = nullptr; }
            FOREACH_SIGNAL(UNHOOK_SIGNAL_WRAPPER)
            #undef UNHOOK_SIGNAL_WRAPPER
        }

        #undef FOREACH_SIGNAL
    #else
        SignalToStacktraceScope::SignalToStacktraceScope() { }
        SignalToStacktraceScope::~SignalToStacktraceScope() { }
    #endif

然后SignalToStacktraceScope在每个测试功能的顶部放置一个(或包装BOOST_TEST_CASE宏以添加它)。在测试开始时做一次不会有帮助,因为 Boost 会继续替换它。

4

0 回答 0