Merge #12692: Add configure options for various -fsanitize flags
6feb46c
Add --with-sanitizers option to configure (Evan Klitzke)
Pull request description:
This adds configure options for `-fsanitize=address`, `-fsanitize=thread`, and `-fsanitize=undefined` which are all disabled by default. These flags are useful for developers who wish to do additional safety checking. Note that some of these are mutually incompatible, and these may have a large performance overhead.
There's some kind of strange logic required to properly check for the availability of these flags in a way that works on both GCC and Clang, hopefully the comments make it clear what's going on.
Tree-SHA512: 2d6fe402799110e59ee452dddf37f7ca2d26a7fecec50be25c8a134e4a20beb31f1e8f438dffd443641562418075896d1eeb450623425b272d80e05e3027a587
This commit is contained in:
commit
de6bdfd78f
3 changed files with 81 additions and 2 deletions
28
configure.ac
28
configure.ac
|
@ -219,6 +219,12 @@ AC_ARG_ENABLE([debug],
|
||||||
[enable_debug=$enableval],
|
[enable_debug=$enableval],
|
||||||
[enable_debug=no])
|
[enable_debug=no])
|
||||||
|
|
||||||
|
# Enable different -fsanitize options
|
||||||
|
AC_ARG_WITH([sanitizers],
|
||||||
|
[AS_HELP_STRING([--with-sanitizers],
|
||||||
|
[comma separated list of extra sanitizers to build with (default is none enabled)])],
|
||||||
|
[use_sanitizers=$withval])
|
||||||
|
|
||||||
# Enable gprof profiling
|
# Enable gprof profiling
|
||||||
AC_ARG_ENABLE([gprof],
|
AC_ARG_ENABLE([gprof],
|
||||||
[AS_HELP_STRING([--enable-gprof],
|
[AS_HELP_STRING([--enable-gprof],
|
||||||
|
@ -247,6 +253,26 @@ if test "x$enable_debug" = xyes; then
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test x$use_sanitizers != x; then
|
||||||
|
# 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
|
||||||
|
AX_CHECK_COMPILE_FLAG(
|
||||||
|
[[-fsanitize=$use_sanitizers]],
|
||||||
|
[[SANITIZER_CXXFLAGS=-fsanitize=$use_sanitizers]],
|
||||||
|
[AC_MSG_ERROR([compiler did not accept requested flags])])
|
||||||
|
|
||||||
|
# Some compilers (e.g. GCC) require additional libraries like libasan,
|
||||||
|
# libtsan, libubsan, etc. Make sure linking still works with the sanitize
|
||||||
|
# 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.
|
||||||
|
AX_CHECK_LINK_FLAG(
|
||||||
|
[[-fsanitize=$use_sanitizers]],
|
||||||
|
[[SANITIZER_LDFLAGS=-fsanitize=$use_sanitizers]],
|
||||||
|
[AC_MSG_ERROR([linker did not accept requested flags, you are missing required libraries])])
|
||||||
|
fi
|
||||||
|
|
||||||
ERROR_CXXFLAGS=
|
ERROR_CXXFLAGS=
|
||||||
if test "x$enable_werror" = "xyes"; then
|
if test "x$enable_werror" = "xyes"; then
|
||||||
if test "x$CXXFLAG_WERROR" = "x"; then
|
if test "x$CXXFLAG_WERROR" = "x"; then
|
||||||
|
@ -1258,6 +1284,8 @@ AC_SUBST(HARDENED_CPPFLAGS)
|
||||||
AC_SUBST(HARDENED_LDFLAGS)
|
AC_SUBST(HARDENED_LDFLAGS)
|
||||||
AC_SUBST(PIC_FLAGS)
|
AC_SUBST(PIC_FLAGS)
|
||||||
AC_SUBST(PIE_FLAGS)
|
AC_SUBST(PIE_FLAGS)
|
||||||
|
AC_SUBST(SANITIZER_CXXFLAGS)
|
||||||
|
AC_SUBST(SANITIZER_LDFLAGS)
|
||||||
AC_SUBST(SSE42_CXXFLAGS)
|
AC_SUBST(SSE42_CXXFLAGS)
|
||||||
AC_SUBST(LIBTOOL_APP_LDFLAGS)
|
AC_SUBST(LIBTOOL_APP_LDFLAGS)
|
||||||
AC_SUBST(USE_UPNP)
|
AC_SUBST(USE_UPNP)
|
||||||
|
|
|
@ -243,6 +243,57 @@ make cov
|
||||||
# A coverage report will now be accessible at `./test_bitcoin.coverage/index.html`.
|
# A coverage report will now be accessible at `./test_bitcoin.coverage/index.html`.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Sanitizers**
|
||||||
|
|
||||||
|
Bitcoin can be compiled with various "sanitizers" enabled, which add
|
||||||
|
instrumentation for issues regarding things like memory safety, thread race
|
||||||
|
conditions, or undefined behavior. This is controlled with the
|
||||||
|
`--with-sanitizers` configure flag, which should be a comma separated list of
|
||||||
|
sanitizers to enable. The sanitizer list should correspond to supported
|
||||||
|
`-fsanitize=` options in your compiler. These sanitizers have runtime overhead,
|
||||||
|
so they are most useful when testing changes or producing debugging builds.
|
||||||
|
|
||||||
|
Some examples:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Enable both the address sanitizer and the undefined behavior sanitizer
|
||||||
|
./configure --with-sanitizers=address,undefined
|
||||||
|
|
||||||
|
# Enable the thread sanitizer
|
||||||
|
./configure --with-sanitizers=thread
|
||||||
|
```
|
||||||
|
|
||||||
|
If you are compiling with GCC you will typically need to install corresponding
|
||||||
|
"san" libraries to actually compile with these flags, e.g. libasan for the
|
||||||
|
address sanitizer, libtsan for the thread sanitizer, and libubsan for the
|
||||||
|
undefined sanitizer. If you are missing required libraries, the configure script
|
||||||
|
will fail with a linker error when testing the sanitizer flags.
|
||||||
|
|
||||||
|
The test suite should pass cleanly with the `thread` and `undefined` sanitizers,
|
||||||
|
but there are a number of known problems when using the `address` sanitizer. The
|
||||||
|
address sanitizer is known to fail in
|
||||||
|
[sha256_sse4::Transform](/src/crypto/sha256_sse4.cpp) which makes it unusable
|
||||||
|
unless you also use `--disable-asm` when running configure. We would like to fix
|
||||||
|
sanitizer issues, so please send pull requests if you can fix any errors found
|
||||||
|
by the address sanitizer (or any other sanitizer).
|
||||||
|
|
||||||
|
Not all sanitizer options can be enabled at the same time, e.g. trying to build
|
||||||
|
with `--with-sanitizers=address,thread` will fail in the configure script as
|
||||||
|
these sanitizers are mutually incompatible. Refer to your compiler manual to
|
||||||
|
learn more about these options and which sanitizers are supported by your
|
||||||
|
compiler.
|
||||||
|
|
||||||
|
Additional resources:
|
||||||
|
|
||||||
|
* [AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html)
|
||||||
|
* [LeakSanitizer](https://clang.llvm.org/docs/LeakSanitizer.html)
|
||||||
|
* [MemorySanitizer](https://clang.llvm.org/docs/MemorySanitizer.html)
|
||||||
|
* [ThreadSanitizer](https://clang.llvm.org/docs/ThreadSanitizer.html)
|
||||||
|
* [UndefinedBehaviorSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html)
|
||||||
|
* [GCC Instrumentation Options](https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html)
|
||||||
|
* [Google Sanitizers Wiki](https://github.com/google/sanitizers/wiki)
|
||||||
|
* [Issue #12691: Enable -fsanitize flags in Travis](https://github.com/bitcoin/bitcoin/issues/12691)
|
||||||
|
|
||||||
Locking/mutex usage notes
|
Locking/mutex usage notes
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
|
|
||||||
DIST_SUBDIRS = secp256k1 univalue
|
DIST_SUBDIRS = secp256k1 univalue
|
||||||
|
|
||||||
AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) $(GPROF_LDFLAGS)
|
AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) $(GPROF_LDFLAGS) $(SANITIZER_LDFLAGS)
|
||||||
AM_CXXFLAGS = $(HARDENED_CXXFLAGS) $(ERROR_CXXFLAGS) $(GPROF_CXXFLAGS)
|
AM_CXXFLAGS = $(HARDENED_CXXFLAGS) $(ERROR_CXXFLAGS) $(GPROF_CXXFLAGS) $(SANITIZER_CXXFLAGS)
|
||||||
AM_CPPFLAGS = $(HARDENED_CPPFLAGS)
|
AM_CPPFLAGS = $(HARDENED_CPPFLAGS)
|
||||||
EXTRA_LIBRARIES =
|
EXTRA_LIBRARIES =
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue