mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-25 16:10:33 +02:00
Merge bitcoin/bitcoin#31992: cmake: Avoid fuzzer "multiple definition of `main'" errors
57d8b1f1b3375452213c48ce80e8207e2fe53ebc cmake: Avoid fuzzer "multiple definition of `main'" errors (Ryan Ofsky) Pull request description: This change builds libraries with `-fsanitize=fuzzer-no-link` instead of `-fsanitize=fuzzer` when the cmake `-DSANITIZERS=fuzzer` option is specified. This is necessary to make fuzzing and IPC cmake options compatible with each other and avoid CI failures in #30975 which enables IPC in the fuzzer CI build: https://cirrus-ci.com/task/5366255504326656?logs=ci#L2817 https://cirrus-ci.com/task/5233064575500288?logs=ci#L2384 The failures can also be reproduced by checking out #31741 and building with `cmake -B build -DBUILD_FOR_FUZZING=ON -DSANITIZERS=fuzzer -DENABLE_IPC=ON` with this fix reverted. The fix updates the cmake build so when `-DSANITIZERS=fuzzer` is specified, the fuzz test binary is built with `-fsanitize=fuzzer` (so it can use libFuzzer's main function), and libraries are built with `-fsanitize=fuzzer-no-link` (so they can be linked into other executables with their own main functions). Previously when `-DSANITIZERS=fuzzer` was specified, `-fsanitize=fuzzer` was applied to ALL libraries and executables. This was inappropriate because it made it impossible to build any executables other than the fuzz test executable without triggering link errors: - `` multiple definition of `main' `` - `` "undefined reference to `LLVMFuzzerTestOneInput' `` if they depended on any libraries instrumented for fuzzing. This was especially a problem when the `ENABLE_IPC` option was set because it made building the `mpgen` code generator impossible so nothing else that depended on generated sources, including the fuzz test binary, could be built either. This commit was previously part of https://github.com/bitcoin/bitcoin/pull/31741 and had some discussion there starting in https://github.com/bitcoin/bitcoin/pull/31741#pullrequestreview-2619682385 --- This PR is part of the [process separation project](https://github.com/bitcoin/bitcoin/issues/28722). ACKs for top commit: hebasto: ACK 57d8b1f1b3375452213c48ce80e8207e2fe53ebc, tested on Ubuntu 24.04. Tree-SHA512: 4011adbc0b08742e83cf7c0560d3d5b5694a863358e6ac9a21239626b4a8fedceca66db34b5a46136a7b26849bb1d8710c894689322ae97e1c407687c3f57d50
This commit is contained in:
commit
4c1906a500
@ -346,13 +346,28 @@ target_link_libraries(core_interface INTERFACE
|
||||
Threads::Threads
|
||||
)
|
||||
|
||||
# Define sanitize_interface with -fsanitize flags intended to apply to all
|
||||
# libraries and executables.
|
||||
add_library(sanitize_interface INTERFACE)
|
||||
target_link_libraries(core_interface INTERFACE sanitize_interface)
|
||||
if(SANITIZERS)
|
||||
# Transform list of sanitizers into -fsanitize flags, replacing "fuzzer" with
|
||||
# "fuzzer-no-link" in sanitize_interface flags, and moving "fuzzer" to
|
||||
# fuzzer_interface flags. If -DSANITIZERS=fuzzer is specified, the fuzz test
|
||||
# binary should be built with -fsanitize=fuzzer (so it can use libFuzzer's
|
||||
# main function), but libraries should be built with -fsanitize=fuzzer-no-link
|
||||
# (so they can be linked into other executables that have their own main
|
||||
# functions).
|
||||
string(REGEX REPLACE "(^|,)fuzzer($|,)" "\\1fuzzer-no-link\\2" sanitize_opts "${SANITIZERS}")
|
||||
set(fuzz_flag "")
|
||||
if(NOT sanitize_opts STREQUAL SANITIZERS)
|
||||
set(fuzz_flag "-fsanitize=fuzzer")
|
||||
endif()
|
||||
|
||||
# First check if the compiler accepts flags. If an incompatible pair like
|
||||
# -fsanitize=address,thread is used here, this check will fail. This will also
|
||||
# fail if a bad argument is passed, e.g. -fsanitize=undfeined
|
||||
try_append_cxx_flags("-fsanitize=${SANITIZERS}" TARGET sanitize_interface
|
||||
try_append_cxx_flags("-fsanitize=${sanitize_opts}" TARGET sanitize_interface
|
||||
RESULT_VAR cxx_supports_sanitizers
|
||||
SKIP_LINK
|
||||
)
|
||||
@ -365,12 +380,11 @@ if(SANITIZERS)
|
||||
# flag. This is a separate check so we can give a better error message when
|
||||
# the sanitize flags are supported by the compiler but the actual sanitizer
|
||||
# libs are missing.
|
||||
try_append_linker_flag("-fsanitize=${SANITIZERS}" VAR SANITIZER_LDFLAGS
|
||||
try_append_linker_flag("-fsanitize=${sanitize_opts}" VAR SANITIZER_LDFLAGS
|
||||
SOURCE "
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
extern \"C\" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; }
|
||||
__attribute__((weak)) // allow for libFuzzer linking
|
||||
int main() { return 0; }
|
||||
"
|
||||
RESULT_VAR linker_supports_sanitizers
|
||||
@ -382,8 +396,10 @@ if(SANITIZERS)
|
||||
endif()
|
||||
target_link_options(sanitize_interface INTERFACE ${SANITIZER_LDFLAGS})
|
||||
|
||||
# Define fuzzer_interface with flags intended to apply to the fuzz test binary,
|
||||
# and perform a test compilation to determine correct value of
|
||||
# FUZZ_BINARY_LINKS_WITHOUT_MAIN_FUNCTION.
|
||||
if(BUILD_FUZZ_BINARY)
|
||||
target_link_libraries(core_interface INTERFACE ${FUZZ_LIBS})
|
||||
include(CheckSourceCompilesWithFlags)
|
||||
check_cxx_source_compiles_with_flags("
|
||||
#include <cstdint>
|
||||
@ -391,9 +407,12 @@ if(BUILD_FUZZ_BINARY)
|
||||
extern \"C\" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; }
|
||||
// No main() function.
|
||||
" FUZZ_BINARY_LINKS_WITHOUT_MAIN_FUNCTION
|
||||
LDFLAGS ${SANITIZER_LDFLAGS}
|
||||
LDFLAGS ${SANITIZER_LDFLAGS} ${fuzz_flag}
|
||||
LINK_LIBRARIES ${FUZZ_LIBS}
|
||||
)
|
||||
add_library(fuzzer_interface INTERFACE)
|
||||
target_link_options(fuzzer_interface INTERFACE ${fuzz_flag})
|
||||
target_link_libraries(fuzzer_interface INTERFACE ${FUZZ_LIBS})
|
||||
endif()
|
||||
|
||||
include(AddBoostIfNeeded)
|
||||
|
@ -138,6 +138,7 @@ add_executable(fuzz
|
||||
)
|
||||
target_link_libraries(fuzz
|
||||
core_interface
|
||||
fuzzer_interface
|
||||
test_fuzz
|
||||
bitcoin_cli
|
||||
bitcoin_common
|
||||
|
Loading…
x
Reference in New Issue
Block a user