aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac28
-rw-r--r--doc/developer-notes.md51
-rw-r--r--src/Makefile.am4
3 files changed, 81 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac
index 4f57750a1a..c422914a26 100644
--- a/configure.ac
+++ b/configure.ac
@@ -219,6 +219,12 @@ AC_ARG_ENABLE([debug],
[enable_debug=$enableval],
[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
AC_ARG_ENABLE([gprof],
[AS_HELP_STRING([--enable-gprof],
@@ -247,6 +253,26 @@ if test "x$enable_debug" = xyes; then
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=
if test "x$enable_werror" = "xyes"; then
if test "x$CXXFLAG_WERROR" = "x"; then
@@ -1258,6 +1284,8 @@ AC_SUBST(HARDENED_CPPFLAGS)
AC_SUBST(HARDENED_LDFLAGS)
AC_SUBST(PIC_FLAGS)
AC_SUBST(PIE_FLAGS)
+AC_SUBST(SANITIZER_CXXFLAGS)
+AC_SUBST(SANITIZER_LDFLAGS)
AC_SUBST(SSE42_CXXFLAGS)
AC_SUBST(LIBTOOL_APP_LDFLAGS)
AC_SUBST(USE_UPNP)
diff --git a/doc/developer-notes.md b/doc/developer-notes.md
index 8f06ee4eca..3be599623a 100644
--- a/doc/developer-notes.md
+++ b/doc/developer-notes.md
@@ -204,6 +204,57 @@ make cov
# 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
-------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 7c2fe56d9d..3ff8958960 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -4,8 +4,8 @@
DIST_SUBDIRS = secp256k1 univalue
-AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) $(GPROF_LDFLAGS)
-AM_CXXFLAGS = $(HARDENED_CXXFLAGS) $(ERROR_CXXFLAGS) $(GPROF_CXXFLAGS)
+AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) $(GPROF_LDFLAGS) $(SANITIZER_LDFLAGS)
+AM_CXXFLAGS = $(HARDENED_CXXFLAGS) $(ERROR_CXXFLAGS) $(GPROF_CXXFLAGS) $(SANITIZER_CXXFLAGS)
AM_CPPFLAGS = $(HARDENED_CPPFLAGS)
EXTRA_LIBRARIES =