Skip to content

Commit 6feb46c

Browse files
committed
Add --with-sanitizers option to configure
This enables the use of different compiler sanitizers, coresponding to the -fsanitize option in GCC and Clang.
1 parent 0a01843 commit 6feb46c

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
@@ -204,6 +204,57 @@ make cov
204204
# A coverage report will now be accessible at `./test_bitcoin.coverage/index.html`.
205205
```
206206

207+
**Sanitizers**
208+
209+
Bitcoin can be compiled with various "sanitizers" enabled, which add
210+
instrumentation for issues regarding things like memory safety, thread race
211+
conditions, or undefined behavior. This is controlled with the
212+
`--with-sanitizers` configure flag, which should be a comma separated list of
213+
sanitizers to enable. The sanitizer list should correspond to supported
214+
`-fsanitize=` options in your compiler. These sanitizers have runtime overhead,
215+
so they are most useful when testing changes or producing debugging builds.
216+
217+
Some examples:
218+
219+
```bash
220+
# Enable both the address sanitizer and the undefined behavior sanitizer
221+
./configure --with-sanitizers=address,undefined
222+
223+
# Enable the thread sanitizer
224+
./configure --with-sanitizers=thread
225+
```
226+
227+
If you are compiling with GCC you will typically need to install corresponding
228+
"san" libraries to actually compile with these flags, e.g. libasan for the
229+
address sanitizer, libtsan for the thread sanitizer, and libubsan for the
230+
undefined sanitizer. If you are missing required libraries, the configure script
231+
will fail with a linker error when testing the sanitizer flags.
232+
233+
The test suite should pass cleanly with the `thread` and `undefined` sanitizers,
234+
but there are a number of known problems when using the `address` sanitizer. The
235+
address sanitizer is known to fail in
236+
[sha256_sse4::Transform](/src/crypto/sha256_sse4.cpp) which makes it unusable
237+
unless you also use `--disable-asm` when running configure. We would like to fix
238+
sanitizer issues, so please send pull requests if you can fix any errors found
239+
by the address sanitizer (or any other sanitizer).
240+
241+
Not all sanitizer options can be enabled at the same time, e.g. trying to build
242+
with `--with-sanitizers=address,thread` will fail in the configure script as
243+
these sanitizers are mutually incompatible. Refer to your compiler manual to
244+
learn more about these options and which sanitizers are supported by your
245+
compiler.
246+
247+
Additional resources:
248+
249+
* [AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html)
250+
* [LeakSanitizer](https://clang.llvm.org/docs/LeakSanitizer.html)
251+
* [MemorySanitizer](https://clang.llvm.org/docs/MemorySanitizer.html)
252+
* [ThreadSanitizer](https://clang.llvm.org/docs/ThreadSanitizer.html)
253+
* [UndefinedBehaviorSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html)
254+
* [GCC Instrumentation Options](https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html)
255+
* [Google Sanitizers Wiki](https://github.com/google/sanitizers/wiki)
256+
* [Issue #12691: Enable -fsanitize flags in Travis](https://github.com/bitcoin/bitcoin/issues/12691)
257+
207258
Locking/mutex usage notes
208259
-------------------------
209260

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)