-
Notifications
You must be signed in to change notification settings - Fork 142
Feat: fuzz tests #763
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat: fuzz tests #763
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Build 2700 of commit caff4b7 has completed with FAILURE
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Build 2702 of commit 927b21f has completed with FAILURE
Signed-off-by: Anton Pryakhin <apryakhin1@bloomberg.net>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Build 2712 of commit c89f0a2 has completed with FAILURE
bin/build-fuzz.sh
Outdated
CMAKE_OPTIONS=(\ | ||
-DBDE_BUILD_TARGET_64=ON \ | ||
-DBDE_BUILD_TARGET_SAFE=ON \ | ||
-DBDE_BUILD_TARGET_CPP20=ON \ | ||
-DCMAKE_BUILD_TYPE=Debug \ | ||
-DCMAKE_INSTALL_LIBDIR="lib" \ | ||
-DCMAKE_INSTALL_PREFIX="${DIR_INSTALL}" \ | ||
-DCMAKE_MODULE_PATH="${DIR_THIRDPARTY}/bde-tools/cmake;${DIR_THIRDPARTY}/bde-tools/BdeBuildSystem" \ | ||
-DCMAKE_PREFIX_PATH="${DIR_INSTALL}" \ | ||
-DCMAKE_TOOLCHAIN_FILE="${DIR_THIRDPARTY}/bde-tools/BdeBuildSystem/toolchains/linux/clang-default.cmake" \ | ||
-DCMAKE_CXX_FLAGS="-fsanitize=fuzzer-no-link" \ | ||
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ | ||
-DINSTALL_TARGETS=fuzztests) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should start moving these configs into CMakePresets.json, so we can manage all the commonalities between these build modes.
Can this be replaced with a preset called fuzz-tests
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added a preset for non-parametrized flags
src/fuzz-tests/CMakeLists.txt
Outdated
|
||
file(GLOB sources "*fuzzer.cpp") | ||
foreach (source ${sources}) | ||
string(REGEX MATCH "\/([A-Za-z_]+)\.cpp$" _ ${source}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why regex match if we glob all the .cpp files in the directory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
simplified this
src/fuzz-tests/CMakeLists.txt
Outdated
target_bmq_default_compiler_flags(${targetName}) | ||
target_include_directories(${targetName} PRIVATE ${fuzz-tests_INCLUDE_DIRS}) | ||
target_link_libraries(${targetName} PRIVATE ${fuzz-tests_PCDEPS}) | ||
target_link_options(${targetName} PRIVATE "-fsanitize=fuzzer") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usually we set sanitizer flags in the toolchain file, we may want to provide one based off of the one we'd be using from https://github.com/bloomberg/bde-tools/tree/main/cmake/toolchains/linux
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved all the flags to docker/sanitizers/clang-libcxx-sanitizer.cmake
src/fuzz-tests/CMakeLists.txt
Outdated
foreach (source ${sources}) | ||
string(REGEX MATCH "\/([A-Za-z_]+)\.cpp$" _ ${source}) | ||
set(targetName ${CMAKE_MATCH_1}) | ||
add_executable(${targetName} ${source}) | ||
|
||
target_bmq_default_compiler_flags(${targetName}) | ||
target_include_directories(${targetName} PRIVATE ${fuzz-tests_INCLUDE_DIRS}) | ||
target_link_libraries(${targetName} PRIVATE ${fuzz-tests_PCDEPS}) | ||
target_link_options(${targetName} PRIVATE "-fsanitize=fuzzer") | ||
|
||
set_target_properties(${targetName} | ||
PROPERTIES OUTPUT_NAME ${targetName}) | ||
|
||
# Add the current tutorial to the 'fuzztests' rule | ||
add_dependencies("fuzztests" ${targetName}) | ||
endforeach() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a nontrivial enough bit of CMake that it should be put in a function and documented
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
CMakeLists.txt
Outdated
if (installIT) | ||
set(BMQ_TARGET_BMQ_NEEDED YES) | ||
set(BMQ_TARGET_MQB_NEEDED YES) | ||
set(BMQ_TARGET_BMQBRKR_NEEDED YES) | ||
set(BMQ_TARGET_BMQTOOL_NEEDED YES) | ||
endif() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this IT install rules related to fuzz testing? Can we have a separate PR for it if not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. It's not related directly to the fuzz tests
Signed-off-by: Anton Pryakhin <apryakhin1@bloomberg.net>
Signed-off-by: Anton Pryakhin <apryakhin1@bloomberg.net>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Build 2735 of commit db59087 has completed with FAILURE
Signed-off-by: Anton Pryakhin <apryakhin1@bloomberg.net>
Signed-off-by: Anton Pryakhin <apryakhin1@bloomberg.net>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Build 2739 of commit 9fb98f6 has completed with FAILURE
Co-authored-by: Taylor Foxhall <lxmachina@gmail.com> Signed-off-by: Anton Pryakhin <antonpryakhin@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Build 2749 of commit d7eb932 has completed with FAILURE
Signed-off-by: Anton Pryakhin <apryakhin1@bloomberg.net>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Build 2754 of commit e11b880 has completed with FAILURE
docker/sanitizers/build_sanitizer.sh
Outdated
if [ "${FUZZER}" == "on" ]; then | ||
export FUZZER_FLAG="fuzzer-no-link" | ||
else | ||
export CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES="/usr/include;/usr/include/clang/${LLVM_VERSION}/include" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this in the else
branch?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default standard library include paths contain libstdc++
headers. We don't want to change it for fuzz-tests. I didn't want to brake anything for the old workflows, so I desided to leave it in the else
branch. However this doesn't look like correct include paths for libc++
. We set this path properly later in the toolchain:
blazingmq/docker/sanitizers/clang-libcxx-sanitizer.cmake
Lines 48 to 52 in e1b5b1b
string(CONCAT TOOLCHAIN_CXX_FLAGS | |
"${TOOLCHAIN_CXX_FLAGS} " | |
"-stdlib=libc++ " | |
"-I${LIBCXX_BUILD_PATH}/include/c++/v1 " | |
) |
So I've got rid of this branch at all and added a flag that removes default include paths for non-fuzz case
|
||
if [[ -z "${2}" || ("${2}" != "on" && "${2}" != "off") ]]; then | ||
echo 'Error: Wrong fuzzer argument. It can be either "on" or "off"' >&2 | ||
echo ' (Usage: build_sanitizer.sh <sanitizer-name> <fuzzer>)' >&2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a section to the comment block at the top with a usage example?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
"-stdlib=libc++ " | ||
"-I${LIBCXX_BUILD_PATH}/include/c++/v1 " | ||
) | ||
if(DEFINED ENV{LIBCXX_BUILD_PATH}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In what build configuration are we using libc++? Just when fuzzers are disabled? I think we should be consistent about which standard library we use. It seems like we'd lose some instrumentation coverage if we don't custom build LLVM here. My understanding is we have this kind of matrix:
Sanitizer | Fuzz? | std choice |
---|---|---|
ASAN | no | libc++ instrumented |
MSAN | no | libc++ instrumented |
TSAN | no | libc++ instrumented |
UBSAN | no | libc++ instrumented |
ASAN | yes | libstd++ |
That makes me kind of think that the fuzz test builds are kind of exceptional and should probably have their own build rules
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct. But these two workflows also have a lot in common - all dependencies, except the standard library, instumented with sanitizers. So it's very convenient to reuse this toolchain. Do we really want another toolchain for that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I think that's fair
src/fuzz-tests/CMakeLists.txt
Outdated
add_custom_target("fuzztests") | ||
|
||
find_package(BdeBuildSystem REQUIRED) | ||
bbs_read_metadata(PACKAGE fuzz-tests) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not a valid BDE package name, but BDE also doesn't really define a clear way for organizing a separate package with dedicated test executables. I'm going to recommend we invent the following conventions:
- Fuzz tests should have the suffix
.fuzz.cpp
- This specific package of fuzz tests should live in
src/standalones/s_bmqfuzz
(maybe we can consult with them on what their opinions about this would be?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've asked BDE team about fuzz tests. They build them in a slightly different way. They put each fuzz test to the test driver of the corresponding component. Here is an example. However they didn't integrate neither with BFuzz nor with oss-fuzz. They run their fuzz tests locally instead. What do you think? Should we do the same with our tests?
src/fuzz-tests/CMakeLists.txt
Outdated
add_dependencies("fuzztests" ${targetName}) | ||
endfunction() | ||
|
||
file(GLOB sources "*fuzzer.cpp") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably should get this list from ${fuzz-tests_SOURCE_FILES}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
Signed-off-by: Anton Pryakhin <apryakhin1@bloomberg.net>
Co-authored-by: Taylor Foxhall <lxmachina@gmail.com> Signed-off-by: Anton Pryakhin <antonpryakhin@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Build 2779 of commit 402061a has completed with FAILURE
Signed-off-by: Anton Pryakhin <apryakhin1@bloomberg.net>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Build 2780 of commit 67d8867 has completed with FAILURE
This PR inroduces a new job to sanitizers workflow. The job builds Fuzz-tests and their dependencies instrumented with address sanitizer. This job is launched in parallel with other sanitizers after a PR is approved. The fuzz tests sources reside in
src/standalones/s_bmqfuzz
. Three tests are added so far:s_bmqfuzz_eval.cpp
targetsBloombergLP::bmqeval::SimpleEvaluator::compile
s_bmqfuzz_parseutil.cpp
targetsBloombergLP::mqbcmd::ParseUtil::parse
s_bmqfuzz_bmqt_uri.cpp
targetsBloombergLP::bmqt::UriParser::parse
There is also a script for building them locally bin/build-fuzz.sh