-
Notifications
You must be signed in to change notification settings - Fork 5
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
Enable ASan in all components, switch stdlib to libc++, switch to lld #741
Conversation
production/CMakeLists.txt
Outdated
endif() | ||
|
||
# Debug build-specific options. | ||
if(CMAKE_BUILD_TYPE STREQUAL "Debug") | ||
set(GAIA_COMPILE_FLAGS "-c -Wall -Wextra -O0 -g -fno-limit-debug-info -ftime-trace") | ||
set(GAIA_COMPILE_FLAGS "-c -Wall -Wextra -O0 -g -fno-limit-debug-info -fno-omit-frame-pointer -fno-optimize-sibling-calls -ftime-trace") |
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.
Looking at other projects I don't get why we use our own GAIA_COMPILE_FLAGS
and GAIA_LINKER_FLAGS
. Every time you have some arguments you want to apply both to Gaia and other code you need to set it twice. Not something that need to be addressed in this PR, but maybe you know why.
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 agree, I don't think it's proper usage of cmake and I've wanted to fix it for a while. But it took so much fiddling to get these changes to work that I'd like to reserve that for a separate PR.
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.
Cool, I just wanted to know if there was a strong reason to keep them.
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.
The idea was to share the default compilation/linking flags across the project. If there's a better way to do that, we should use it.
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.
It would be easy enough to just use add_compile_options()
/add_link_options()
at the top level, with the current contents of GAIA_*_FLAGS
, but I'm worried that might break some 3rd-party code. I'll try that once this PR is checked in.
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.
Another thing is:
Additionally, since we don't force lld to be used via linker flags, you need to set the following environment variables in your .bashrc or equivalent:
Why don't we force it?
production/CMakeLists.txt
Outdated
add_compile_options(-fno-sanitize-recover=all) | ||
add_link_options(-fno-sanitize-recover=all) | ||
|
||
# Enabling ASan always enables UBSan as well (they are compatible so we have no separate option for UBSan). | ||
if("$CACHE{SANITIZER}" STREQUAL "ASAN") | ||
add_compile_options(-fsanitize=address -fsanitize=undefined) | ||
add_link_options(-fsanitize=address -fsanitize=undefined) |
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.
Do these 2 commands affect GAIA flags?
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.
Yes, they affect the compile/link flags for everything we build. That's the intention (again, everything must be built with ASan after switching to libc++).
@@ -165,8 +161,8 @@ if(Python3_FOUND AND pybind11_FOUND) | |||
# See https://github.com/pybind/pybind11/issues/1604 for inclusion of -fsized-deallocation for C++17 | |||
set_target_properties(gaia_db_pybind PROPERTIES COMPILE_FLAGS | |||
"${GAIA_COMPILE_FLAGS} -Wno-deprecated-register -Wno-unused-parameter -fsized-deallocation") | |||
set_target_properties(gaia_db_pybind PROPERTIES LINK_FLAGS ${GAIA_LINK_FLAGS}) |
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.
It could be a good moment to remove both the python
and the jni
stuff....
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 don't think that's in scope for this PR, and it would need prior discussion.
add_link_options(-fno-sanitize-recover=all) | ||
|
||
# Enabling ASan always enables UBSan as well (they are compatible so we have no separate option for UBSan). | ||
if("$CACHE{SANITIZER}" STREQUAL "ASAN") |
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 is
$CACHE{SANITIZER}
inside"
? - Why are you using
$CACHE
to accessSANITIZER
?
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.
- It turned out that I couldn't use the bare variable reference (
CACHE{SANITIZER}
) withSTREQUAL
, so I needed to compare two strings, and it's safer to quote a string value. - Any variable specified with
-D
on the cmake command line is automatically a cache variable.
production/CMakeLists.txt
Outdated
if(ENABLE_ASAN) | ||
set(GAIA_COMPILE_FLAGS "${GAIA_COMPILE_FLAGS} -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all -fno-omit-frame-pointer") | ||
set(GAIA_LINK_FLAGS "${GAIA_LINK_FLAGS} -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all") | ||
if (BUILD_SHARED_LIBRARY AND RUN_TESTS) |
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.
Where this BUILD_SHARED_LIBRARY
come from, or better how it affects Gaia since we almost build everything static.
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.
OMG, good catch! Cut'n'paste detritus from SO...
We could force it, I just want to avoid unnecessarily passing flags to projects we don't own. But it might be better to pass |
Yes, probably we should set also the compilers since I don't see us using GCC or any other compiler any time soon. (see: https://stackoverflow.com/questions/7031126/switching-between-gcc-and-clang-llvm-using-cmake) |
production/CMakeLists.txt
Outdated
@@ -33,6 +31,23 @@ set(CMAKE_CXX_STANDARD_REQUIRED True) | |||
# Ensure debug builds have the DEBUG flag defined. | |||
add_compile_options("$<$<CONFIG:DEBUG>:-DDEBUG>") | |||
|
|||
# Ensure that PIE flags are actually passed to the linker. |
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 a quick comment on what PIE flags are and are needed for?
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.
Added comment for next commit.
So the top answer suggests using |
@@ -60,6 +60,9 @@ option(WITH_WINDOWS_UTF8_FILENAMES "use UTF8 as characterset for opening files, | |||
if (WITH_WINDOWS_UTF8_FILENAMES) | |||
add_definitions(-DROCKSDB_WINDOWS_UTF8_FILENAMES) | |||
endif() | |||
# We always want to enable the attributes selectively disabling UBSan. |
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.
This doesn't read clearly to me. Is a word missing in this sentence?
My questions:
- Which attributes?
- Does "selectively" refer to enabling the attributes or to disabling UBSan? What does it mean exactly?
- What's the connection between enabling attributes and disabling UBSan?
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.
This is moot because I no longer enable UBSan on 3rd-party components when ASan is enabled via the SANITIZER
option.
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 am not clear on the meaning of a comment, but otherwise I have no suggestions/requests for change.
…LLD to be used everywhere
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.
If you can add the -fno-limit-debug-info
flag to LLVm cool, otherwise no worries.
production/CMakeLists.txt
Outdated
if (BUILD_SHARED_LIBRARY AND RUN_TESTS) | ||
message(FATAL_ERROR "Can't build shared library and run tests at same time") | ||
endif() | ||
set(GAIA_COMPILE_FLAGS "-c -Wall -Wextra -O0 -g3 -ggdb -fno-limit-debug-info -fno-omit-frame-pointer -fno-optimize-sibling-calls -ggnu-pubnames -gsplit-dwarf -ftime-trace") |
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.
Sorry, forgot to mention it. We need -fno-limit-debug-info
also in LLVM, otherwise, it won't be possible to see the values of things such as strings.
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.
Unfortunately there not seem to be one of the LLVM_....
cmake options for this.
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.
Added this flag to all built binaries in latest commit, and verified it is included in the LLVM compile command line.
FYI, in the latest commit I removed the |
I think I've addressed all concerns, so I'm merging without waiting for approvals from the remaining reviewers. I'll copy the README from this PR to the #engineering channel so there are no surprises from new dependencies. |
This change passes compiler/linker flags to all built components to enable AddressSanitizer when
-DSANITIZER=ASAN
is passed tocmake
(default in debug builds), and to uselibc++
rather thanlibstdc++
(which is the default stdlib with clang even though it's the GCC stdlib andlibc++
is the LLVM stdlib). We also set the linker flag-fuse-ld=lld
everywhere to force thelld
linker to be used rather than GNUld
(again the default withclang
even thoughlld
is the LLVM linker). The combination oflibc++
andlld
will make it possible to enable MemorySanitizer in an upcoming PR. Additionally,lld
is reputed to make LLVM builds much faster (particularly debug builds), but I haven't measured the difference. Note that if you aren't usinggdev
, you need to install the following packages (assuming Ubuntu 20.04):If you only install the
lld-10
package but not thelld
package (which installslld-10
as the defaultlld
version on Ubuntu 20.04 but not on 18.04), you may need to create a symlink fromld.lld
told.lld-10
so that linker flags will work properly:(As usual, this is already taken care of for you by
gdev
.)PS: I had to enable ASan in all built components in order to switch to
libc++
, because ASan is able to use a feature called "container overflow detection" whenlibc++
is used (it's annotated to enable this feature). However, this will lead to false positives when any code is linked that wasn't built with ASan, so I had to pass ASan compiler/linker flags to all our third-party components as well. After doing so, I verified that ASan no longer produced false positives. Enabling UBSan on all built components produced runtime errors in LLVM, so for now UBSan is only enabled on Gaia components.