How to Configure Debug Break on Failure and Abort Settings in Catch2

Catch2 provides orthogonal mechanisms to automatically break into a debugger on assertion failures using the -b/--break flag and to terminate test runs after a configurable number of failures using -a/--abort or -x/--abortx.

When debugging test failures in the Catch2 framework, developers often need precise control over execution flow. Learning how to configure debug break on failure and abort settings in Catch2 allows you to automatically pause execution in attached debuggers and limit the scope of failing test runs. These settings can be controlled via command-line flags, compile-time macros, or programmatic configuration through the Catch::Session API.

Enabling Debug Break on Failure

The debug break on failure feature interrupts test execution and transfers control to an attached debugger whenever an assertion fails.

Platform-Specific Implementation

In src/catch2/internal/catch_debugger.hpp, the CATCH_BREAK_INTO_DEBUGGER() macro expands to a lambda that checks Catch::isDebuggerActive() and, if true, invokes the platform-specific CATCH_TRAP() implementation. On MSVC this translates to __debugbreak(), while on Linux it uses raise(SIGTRAP). This macro is injected at every failure handling path within the assertion machinery.

Command-Line Activation

To enable automatic debugger breaks without modifying source code, pass the -b or --break flag when running your test executable:

./tests -b

This activates the default CATCH_BREAK_INTO_DEBUGGER() behavior, causing the process to trap into the debugger only if one is currently attached.

Compile-Time Customization

You can override the default break behavior by defining your own CATCH_BREAK_INTO_DEBUGGER() macro before including any Catch2 headers. This is useful for adding logging or custom breakpoint logic:

// Define custom break behavior before including Catch2
#define CATCH_BREAK_INTO_DEBUGGER() []{ \
    if (Catch::isDebuggerActive()) { \
        std::cerr << "Breaking into debugger..." << std::endl; \
        CATCH_TRAP(); \
    } \
}()

#include <catch2/catch_test_macros.hpp>

This customization is documented in the configuration section covering compile-time overrides for debug break behavior.

Configuring Abort After Failures

The abort after failures mechanism stops the entire test run once a specified failure threshold is reached, which is distinct from the per-test-case abort behavior of REQUIRE versus CHECK.

Immediate Abort on First Failure

Use the -a or --abort flag to terminate the test run immediately after the first failed assertion of any kind:

./tests --abort

Threshold-Based Abort

To abort after a specific number of failures rather than immediately, use the -x or --abortx flag followed by the number:


# Abort after 5 assertion failures (including both CHECK and REQUIRE)

./tests --abortx 5

These flags hook into the test runner's failure counting logic in src/catch2/catch_session.hpp, causing an early exit once the threshold is reached.

Programmatic Configuration

When embedding Catch2 and constructing a custom main function, configure abort thresholds via Catch::Session:

#include <catch2/catch_session.hpp>

int main(int argc, char* argv[]) {
    Catch::Session session;
    // Abort after 3 failures (equivalent to `-x 3`)
    session.configData().abortAfter = 3;
    return session.run(argc, argv);
}

The abortAfter field is part of Catch::ConfigData and controls when the test runner terminates based on accumulated assertion failures.

Key Implementation Files

Understanding where these features reside helps with advanced customization:

Summary

  • Debug break on failure is controlled by the CATCH_BREAK_INTO_DEBUGGER() macro in catch_debugger.hpp, activated via -b/--break or customized at compile time.
  • Abort settings terminate the test run after specified failure counts, configured via -a/--abort (immediate) or -x/--abortx N (threshold).
  • Programmatic control is available through Catch::Session.configData().abortAfter for embedded framework usage.
  • These mechanisms operate independently—break actions pause for debugging while abort actions terminate execution based on failure counts.

Frequently Asked Questions

How do I disable the debug break feature entirely?

Define CATCH_BREAK_INTO_DEBUGGER() as an empty macro before including Catch2 headers. This prevents the automatic debugger break logic from compiling into your binary, effectively disabling the feature regardless of command-line flags.

What is the difference between CHECK and REQUIRE failures regarding abort settings?

CHECK failures increment the failure counter and continue test execution, while REQUIRE failures throw an exception that aborts the current test case immediately. However, the -a/--abort and -x/--abortx flags apply to the cumulative failure count across the entire test run, affecting both assertion types when calculating whether to stop execution.

Can I combine debug break and abort settings in the same test run?

Yes, these settings are orthogonal. You can use ./tests -b -x 5 to break into the debugger on each failure while also ensuring the test run terminates after 5 total failures. The debugger break occurs before the abort check, allowing you to inspect the failure before the process exits.

Why does the debugger break not work when running tests in CI environments?

The CATCH_BREAK_INTO_DEBUGGER() macro checks Catch::isDebuggerActive() before invoking the platform trap. In CI environments without an attached debugger, this check returns false, allowing tests to continue normally. Ensure you have an actual debugger attached (not just running in debug build configuration) for the break to trigger.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →