Skip to content

Commit de6bdfd

Browse files
committed
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
2 parents 252c1b0 + 6feb46c commit de6bdfd

File tree

3 files changed

+81
-2
lines changed

3 files changed

+81
-2
lines changed

configure.ac

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,12 @@ AC_ARG_ENABLE([debug],
219219
[enable_debug=$enableval],
220220
[enable_debug=no])
221221

222+
# Enable different -fsanitize options
223+
AC_ARG_WITH([sanitizers],
224+
[AS_HELP_STRING([--with-sanitizers],
225+
[comma separated list of extra sanitizers to build with (default is none enabled)])],
226+
[use_sanitizers=$withval])
227+
222228
# Enable gprof profiling
223229
AC_ARG_ENABLE([gprof],
224230
[AS_HELP_STRING([--enable-gprof],
@@ -247,6 +253,26 @@ if test "x$enable_debug" = xyes; then
247253
fi
248254
fi
249255

256+
if test x$use_sanitizers != x; then
257+
# First check if the compiler accepts flags. If an incompatible pair like
258+
# -fsanitize=address,thread is used here, this check will fail. This will also
259+
# fail if a bad argument is passed, e.g. -fsanitize=undfeined
260+
AX_CHECK_COMPILE_FLAG(
261+
[[-fsanitize=$use_sanitizers]],
262+
[[SANITIZER_CXXFLAGS=-fsanitize=$use_sanitizers]],
263+
[AC_MSG_ERROR([compiler did not accept requested flags])])
264+
265+
# Some compilers (e.g. GCC) require additional libraries like libasan,
266+
# libtsan, libubsan, etc. Make sure linking still works with the sanitize
267+
# flag. This is a separate check so we can give a better error message when
268+
# the sanitize flags are supported by the compiler but the actual sanitizer
269+
# libs are missing.
270+
AX_CHECK_LINK_FLAG(
271+
[[-fsanitize=$use_sanitizers]],
272+
[[SANITIZER_LDFLAGS=-fsanitize=$use_sanitizers]],
273+
[AC_MSG_ERROR([linker did not accept requested flags, you are missing required libraries])])
274+
fi
275+
250276
ERROR_CXXFLAGS=
251277
if test "x$enable_werror" = "xyes"; then
252278
if test "x$CXXFLAG_WERROR" = "x"; then
@@ -1258,6 +1284,8 @@ AC_SUBST(HARDENED_CPPFLAGS)
12581284
AC_SUBST(HARDENED_LDFLAGS)
12591285
AC_SUBST(PIC_FLAGS)
12601286
AC_SUBST(PIE_FLAGS)
1287+
AC_SUBST(SANITIZER_CXXFLAGS)
1288+
AC_SUBST(SANITIZER_LDFLAGS)
12611289
AC_SUBST(SSE42_CXXFLAGS)
12621290
AC_SUBST(LIBTOOL_APP_LDFLAGS)
12631291
AC_SUBST(USE_UPNP)

doc/developer-notes.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,57 @@ make cov
243243
# A coverage report will now be accessible at `./test_bitcoin.coverage/index.html`.
244244
```
245245

246+
**Sanitizers**
247+
248+
Bitcoin can be compiled with various "sanitizers" enabled, which add
249+
instrumentation for issues regarding things like memory safety, thread race
250+
conditions, or undefined behavior. This is controlled with the
251+
`--with-sanitizers` configure flag, which should be a comma separated list of
252+
sanitizers to enable. The sanitizer list should correspond to supported
253+
`-fsanitize=` options in your compiler. These sanitizers have runtime overhead,
254+
so they are most useful when testing changes or producing debugging builds.
255+
256+
Some examples:
257+
258+
```bash
259+
# Enable both the address sanitizer and the undefined behavior sanitizer
260+
./configure --with-sanitizers=address,undefined
261+
262+
# Enable the thread sanitizer
263+
./configure --with-sanitizers=thread
264+
```
265+
266+
If you are compiling with GCC you will typically need to install corresponding
267+
"san" libraries to actually compile with these flags, e.g. libasan for the
268+
address sanitizer, libtsan for the thread sanitizer, and libubsan for the
269+
undefined sanitizer. If you are missing required libraries, the configure script
270+
will fail with a linker error when testing the sanitizer flags.
271+
272+
The test suite should pass cleanly with the `thread` and `undefined` sanitizers,
273+
but there are a number of known problems when using the `address` sanitizer. The
274+
address sanitizer is known to fail in
275+
[sha256_sse4::Transform](/src/crypto/sha256_sse4.cpp) which makes it unusable
276+
unless you also use `--disable-asm` when running configure. We would like to fix
277+
sanitizer issues, so please send pull requests if you can fix any errors found
278+
by the address sanitizer (or any other sanitizer).
279+
280+
Not all sanitizer options can be enabled at the same time, e.g. trying to build
281+
with `--with-sanitizers=address,thread` will fail in the configure script as
282+
these sanitizers are mutually incompatible. Refer to your compiler manual to
283+
learn more about these options and which sanitizers are supported by your
284+
compiler.
285+
286+
Additional resources:
287+
288+
* [AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html)
289+
* [LeakSanitizer](https://clang.llvm.org/docs/LeakSanitizer.html)
290+
* [MemorySanitizer](https://clang.llvm.org/docs/MemorySanitizer.html)
291+
* [ThreadSanitizer](https://clang.llvm.org/docs/ThreadSanitizer.html)
292+
* [UndefinedBehaviorSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html)
293+
* [GCC Instrumentation Options](https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html)
294+
* [Google Sanitizers Wiki](https://github.com/google/sanitizers/wiki)
295+
* [Issue #12691: Enable -fsanitize flags in Travis](https://github.com/bitcoin/bitcoin/issues/12691)
296+
246297
Locking/mutex usage notes
247298
-------------------------
248299

src/Makefile.am

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
DIST_SUBDIRS = secp256k1 univalue
66

7-
AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) $(GPROF_LDFLAGS)
8-
AM_CXXFLAGS = $(HARDENED_CXXFLAGS) $(ERROR_CXXFLAGS) $(GPROF_CXXFLAGS)
7+
AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) $(GPROF_LDFLAGS) $(SANITIZER_LDFLAGS)
8+
AM_CXXFLAGS = $(HARDENED_CXXFLAGS) $(ERROR_CXXFLAGS) $(GPROF_CXXFLAGS) $(SANITIZER_CXXFLAGS)
99
AM_CPPFLAGS = $(HARDENED_CPPFLAGS)
1010
EXTRA_LIBRARIES =
1111

0 commit comments

Comments
 (0)