Skip to main content

Debug a Finding

CI Fuzz provides an intuitive way to debug a Finding.

note

This workflow applies to C/C++ projects with CMake as a build system.

As an example, we want to fuzz the following (simple) Fuzz Test:

fuzz test example
FUZZ_TEST(const uint8_t *data, size_t size) {
if(std::string((char*)data, size) != "crashing input") {
throw "Crash triggered";
}
}

This Fuzz Test generates a Finding called exciting_eagle.

To debug this Finding, the user can add the macro DEBUG_FINDING(...) to the source file containing the Fuzz Test. This macro receives the name of the Finding as an argument:

fuzz test example
DEBUG_FINDING(exciting_eagle)

FUZZ_TEST(const uint8_t *data, size_t size) {
if(std::string((char*)data, size) != "ci-daemon") {
throw "Crash triggered";
}
}

Furthermore, the user needs to add the test framework of their choice to the Fuzz Test definition in the CMakeLists.txt file:

note

Currently only Google Test is supported.

CMakeLists.txt
add_fuzz_test(fuzz_test fuzz_test.cpp TEST_FRAMEWORK GTEST)

In case the user didn't follow the default installation instructions of Google Test, it's possible to pass the target names of the Google Test libraries:

CMakeLists.txt
add_fuzz_test(fuzz_test fuzz_test.cpp TEST_FRAMEWORK GTEST TEST_FRAMEWORK_LIBS ${GTEST_BOTH_LIBRARIES})

In order to be able to reproduce Findings reliably, the Fuzz Test has to be instrumented with address sanitizer and undefined behaviour sanitizer. The user needs to add the following lines to the top of their CMakeLists.txt before any commands related to the Fuzz Test:

CMakeLists.txt
add_compile_options(-fsanitize=address,undefined)
add_link_options(-fsanitize=address,undefined)

The IDE picks up the macro as a unit test, which in turn calls the Fuzz Test with the crashing input of the Finding:

Debug Finding Macro

The user can directly place a breakpoint in the Fuzz Test and start debugging the Finding:

Debug Finding Macro