-
Notifications
You must be signed in to change notification settings - Fork 37.7k
Add configure options for various -fsanitize flags #12692
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
df37ecb
to
78618b8
Compare
Concept ACK Very nice! |
The code actually looks good with Things are horribly broken if you try to use |
I don't think we should add configure options for every possible sanitation flag. This might confuse people that are trying to build the software with a flurry of options. It looks like the beginning of trying to wrap all compiler options. Which is unnecessary as they can already be passed through What about a single |
@laanwj But the sanitizers are mutually exclusive, right? I.e. you cannot run ASan and TSan at the same time. |
@practicalswift Some are. Some are not. Different compilers may have different limitations in the future as well. |
Also, it should be noted that the downside of these flags is not limited to performance overhead: they may also introduce security issues. (This is why it's discouraged to build your entire system with them enabled.) |
@eklitzke While we're at it – what about allowing for MemorySanitizer (MSan: |
That's a subset right? In that case, the option would take only one argument. I was just illustrating how it generalizes to multiple. Mesa has similar option to provide a comma-separated list of drivers to build in, for example. |
@laanwj Yes, you're right! I think |
configure.ac
Outdated
# libtsan, etc. when using the related -fsanitize flags. Clang works | ||
# differently: it statically links these dependencies. Therefore we can't use | ||
# AC_CHECK_LIB to test this, we need to compile and link. | ||
if test "x$enable_asan" = xyes; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does AX_CHECK_LINK_FLAG not do what we want here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That adds the flags to LDFLAGS, so no.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I think there's a trick to combine these (and remove the m4 file I added).
configure.ac
Outdated
fi | ||
if test "x$enable_tsan" = xyes; then | ||
BITCOIN_CHECK_COMPILE_FLAG_AND_LINK([-fsanitize=thread], | ||
[CXXFLAGS="$CXXFLAGS -fsanitize=thread"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned in the debugging PR, Please add these to a SANITIZE_CXXFLAGS or DEBUG_CXXFLAGS or so, rather than CXXFLAGS directly.
Adding to CXXFLAGS means that future tests will be done with sanitizers enabled, which can cause false-negatives.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will fix
These are good suggestions, I will redo things and put another version of this change. |
On Mar 16, 2018 4:16 PM, "Evan Klitzke" <notifications@github.com> wrote:
*@eklitzke* commented on this pull request.
------------------------------
In configure.ac
<#12692 (comment)>:
@@ -247,6 +268,27 @@ if test "x$enable_debug" = xyes; then
fi
fi
+# Checking for -fsanitize flags works differently from other compiler flags.
+# That's because with GCC there's an implicit linking dependency on libasan,
+# libtsan, etc. when using the related -fsanitize flags. Clang works
+# differently: it statically links these dependencies. Therefore we can't use
+# AC_CHECK_LIB to test this, we need to compile and link.
+if test "x$enable_asan" = xyes; then
Actually I think there's a trick to combine these (and remove the m4 file I
added).
—
You are receiving this because you were assigned.
Reply to this email directly, view it on GitHub
<#12692 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAZdE82U3dp9IDhfkYnRDPPJRz6B_6hXks5tfB2FgaJpZM4Srfdg>
.
The variable used shouldn't matter, the contents just end up on the cmdline.
|
Updated to add a single sanitizer flag. Should be portable to all POSIX systems including traditional /bin/sh. I tried a lot of things with the existing AX_* macros and could not get this to work right without the new m4 file I added. For instance, I tried using AX_LINK_IFELSE after AX_CHECK_COMPILE_FLAG, but that uses CXXFLAGS not the new flags I added, and it has no option to take additional compile flags. That said, there are other options if we don't want the new m4 file:
Let's see how #12695 pans out though before continuing with this. |
configure.ac
Outdated
# supports the flag, but in fact linking would fail. | ||
# | ||
# Clang works differently: it bundles these libraries, and statically links them | ||
# when using -fsanitize. For this reason, using AC_CHECK_LIB is not a good idea, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what distinction you're trying to make here. As far as I can tell, clang/gcc handle this the same way. Of course, how distros configure and distribute them is a different story.
The following works fine for me with a gcc with busted libtsan:
AX_CHECK_LINK_FLAG([[-fsanitize=undefined]],[[SANITIZER_CXXFLAGS="${SANITIZER_CXXFLAGS} -fsanitize=undefined"; SANITIZER_LDFLAGS="${SANITIZER_LDFLAGS} -fsanitize=undefined"]],
[AC_MSG_ERROR([compiler does not support -fsanitize=undefined])], [[$CXXFLAG_WERROR]])
AX_CHECK_LINK_FLAG([[-fsanitize=thread]],[[SANITIZER_CXXFLAGS="${SANITIZER_CXXFLAGS} -fsanitize=thread"; SANITIZER_LDFLAGS="${SANITIZER_LDFLAGS} -fsanitize=thread"]],
[AC_MSG_ERROR([compiler does not support -fsanitize=thread])], [[$CXXFLAG_WERROR]])
The second check (correctly) fails due to a linking error with libtsan:
configure:18545: checking whether the linker accepts -fsanitize=undefined
configure:18564: g++ -m64 -std=c++11 -o conftest -pipe -O2 -I/home/cory/dev/bitcoin2/depends/x86_64-pc-linux-gnu/share/../include/ -L/home/cory/dev/bitcoin2/depends/x86_64-pc-linux-gnu/share/../lib -Werror -fsanitize=undefined conftest.cpp >&5
configure:18564: $? = 0
configure:18574: result: yes
configure:18583: checking whether the linker accepts -fsanitize=thread
configure:18602: g++ -m64 -std=c++11 -o conftest -pipe -O2 -I/home/cory/dev/bitcoin2/depends/x86_64-pc-linux-gnu/share/../include/ -L/home/cory/dev/bitcoin2/depends/x86_64-pc-linux-gnu/share/../lib -Werror -fsanitize=thread conftest.cpp >&5
/tmp/ramfs/tmp/ccFEArS2.o: In function_GLOBAL__sub_I_00099_0_main': conftest.cpp:(.text.startup+0x11): undefined reference to
__tsan_init'
collect2: error: ld returned 1 exit status
I don't understand why you find AX_CHECK_LINK_FLAG insufficient, as it simply does a combined compile/link through the compiler, it doesn't invoke the linker directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll try retesting this.
You're right, I removed the m4 file I added and made this much simpler. The error messages are also much better now. Changes:
Here are some cases I tested. Note that this enables me to provide better error messages. Misspelled option
Options
Options
And for completeness, when everything is installed and valid:
I was able to run the build all the way through including linking with the existing change to src/Makefile.am that just adds the flags to AM_CXXFLAGS, no need to update AM_LDFLAGS. |
7c9eb31
to
257cb24
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utACK 257cb24
It may be a good idea to say something about the new option in developer notes, for example to mention the -fsanitize=address / --disable-asm combination.
Docs added (including the note about |
configure.ac
Outdated
@@ -219,6 +219,12 @@ AC_ARG_ENABLE([debug], | |||
[enable_debug=$enableval], | |||
[enable_debug=no]) | |||
|
|||
# Enable different -fsanitize options | |||
AC_ARG_ENABLE([sanitizer], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mind changing this to AC_ARG_WITH? In autoconf-speak, --enable-foo is intended to be binary (which is why it enables --disable-foo too), and --with-bar is intended to take options.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
configure.ac
Outdated
# supported but libraries are missing. | ||
AX_CHECK_LINK_FLAG( | ||
[[-fsanitize=$enable_sanitizer]], | ||
[[SANITIZER_CXXFLAGS=-fsanitize=$enable_sanitizer]], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add these to a SANITIZER_LDFLAGS as well, and add it to AM_LDFLAGS? I'm nervous that automake/libtool may not always add (all) CXXFLAGS to the link-line. In fact, they really shouldn't be doing that anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
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, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not notate the incompatible functions with a function attribute (no_sanitize("address")
) instead? Of course we'd need to do an autoconf check for that first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could, but there seem to be a lot of them so I don't have a full list of what needs to be disabled yet.
Updated to use the --with form and re-squashed. |
1851744
to
21f01aa
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utACK, thanks.
Nit: --with-sanitizers (rather than --with-sanitizer) would make it more obvious that a list is accepted. Feel free to change if you agree, but it's not worth holding up merge.
I do think that we should notate known false-positives, even if there are lots of them. If nothing else, it would force us to be able to explain why the false-positives are produced in the first place, and help file good upstream bugs for the sanitizers themselves.
It makes sense to add the annotations in another PR, though.
Note that --disable-asm apparently doesn't disable leveldb's crc32 intrinsics as it arguably should. Also, the --enable-asm is passed down to libsecp256k1 which only knows about --with-asm, so assembly ends up being used there as well. I'll PR fixes for those.
So, if --disable-asm is enough to get it working, as I see it that must mean it's sha256_sse4 causing the issues.
This enables the use of different compiler sanitizers, coresponding to the -fsanitize option in GCC and Clang.
utACK 6feb46c |
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
01189ab build: Show enabled sanitizers in configure output (practicalswift) Pull request description: Show enabled sanitizers in `configure` output. Context: @eklitzke excellent addition of `--with-sanitizers` in #12692 Tree-SHA512: b2d52308e3476488fe47cbc059d7f3235aaeefaa2b987003923f6eaacbadf67f0cf22a32a04873d0f54c1867757841e01c8053f86a4d2f59a407b960ac15105f
./configure updates Includes code cherry-picked from the following upstream Bitcoin Core PRs: - bitcoin/bitcoin#6748 - bitcoin/bitcoin#12373 - bitcoin/bitcoin#12692 - bitcoin/bitcoin#12901 - bitcoin/bitcoin#13005 - bitcoin/bitcoin#13445 - bitcoin/bitcoin#12686 - bitcoin/bitcoin#16435 Part of #2074.
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
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
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
01189ab build: Show enabled sanitizers in configure output (practicalswift) Pull request description: Show enabled sanitizers in `configure` output. Context: @eklitzke excellent addition of `--with-sanitizers` in bitcoin#12692 Tree-SHA512: b2d52308e3476488fe47cbc059d7f3235aaeefaa2b987003923f6eaacbadf67f0cf22a32a04873d0f54c1867757841e01c8053f86a4d2f59a407b960ac15105f
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
01189ab build: Show enabled sanitizers in configure output (practicalswift) Pull request description: Show enabled sanitizers in `configure` output. Context: @eklitzke excellent addition of `--with-sanitizers` in bitcoin#12692 Tree-SHA512: b2d52308e3476488fe47cbc059d7f3235aaeefaa2b987003923f6eaacbadf67f0cf22a32a04873d0f54c1867757841e01c8053f86a4d2f59a407b960ac15105f
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.