Skip to content
This repository has been archived by the owner on Oct 15, 2024. It is now read-only.

ASAN: support on clang and fixed GIR buildin with UBSAN #803

Merged
merged 5 commits into from
Nov 18, 2016
Merged

ASAN: support on clang and fixed GIR buildin with UBSAN #803

merged 5 commits into from
Nov 18, 2016

Conversation

rautesamtr
Copy link
Contributor

This commit adds support for llvm/clang adress sanitizer.
It can be can only be enabled in combination with debug on.
e.g. -DENABLE_DEBUG=ON -DENABLE_ASAN=ON Fixes #801
It also fixes problems when compiling GI bindings with the undefined
behavior sanitizer by passing the corresponding libraries (-lubsan
-lasan). Fixes #786

@markus2330
Copy link
Contributor

I would prefer that ENABLE_DEBUG and ENABLE_ASAN work independently.

Is it really required to have -fsanitize=undefined -fsanitize=integer set so that ASAN works?

@rautesamtr
Copy link
Contributor Author

Is it really required to have -fsanitize=undefined -fsanitize=integer set so that ASAN works?

No we can let it work independently. I was waiting on your opinion on this mater anyway.

@rautesamtr
Copy link
Contributor Author

We could make it available as a general option as it should be possible to use it even with gcc as long as llvm/clang is installed.

@markus2330
Copy link
Contributor

markus2330 commented Jun 15, 2016

It is always good to avoid dependencies between options. Its confusing and error-prone.

I expected that ENABLE_ASAN is meant to be compiler-independent. So everyone can step up and write support for other compilers.

E.g. ENABLE_COVERAGE is compiler-independent but currently only does something when gcc is used.

@rautesamtr
Copy link
Contributor Author

GCC supports the -fsanitize=address since 4.8.
I probably just misunderstood, it seems they actually integrated the ASAN from LLVM into GCC so yes it should be compiler independent as long as they support the -fsanitize=address option.

@markus2330
Copy link
Contributor

Then please set -fsanitize=address for both gcc and clang if ENABLE_ASAN was set.

This commit adds support for llvm/clang adress sanitizer.
It can be can only be enabled with `-DENABLE_ASAN=ON`. Fixes #801
It also fixes problems when compiling GI bindings with the undefined
behavior sanitizer by passing the corresponding libraries (-lubsan
-lasan). Fixes #786
@rautesamtr
Copy link
Contributor Author

I am running in some issues with GCC end ASAN enabled:

[ 41%] Linking CXX executable ../../../bin/testmod_type
/usr/bin/ld: ../../../lib/libgtest.a(gtest-all.cc.o): undefined reference to symbol 'pthread_key_delete@@GLIBC_2.2.5'
/usr/lib/../lib/libpthread.so.0: error adding symbols: DSO missing from command line

@rautesamtr
Copy link
Contributor Author

It also looks like i still need to handle libasan selection correctly

We should only pass -lasan when using gcc and ASAN_ENABLED as this
otherwise results in clang linking the gcc sanitizer which in return
results in broken binarys.

Also currently use a workaround to add -lpthread when using ASAN with
gcc. This probably should be moved into the GTest logic of the cmake
files, but i am currently lacking the expertise to do this correctly.
@rautesamtr
Copy link
Contributor Author

rautesamtr commented Jun 15, 2016

Then please set -fsanitize=address for both gcc and clang if ENABLE_ASAN was set.

should work now.

set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address")
# this is currently a workaround so gtests compile with ASAN
#TODO someone with expertise migrate this into LibAddTest
set (COMMON_FLAGS "${COMMON_FLAGS} -lpthread")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is rather a workaround for the gcc asan problem by explicitly adding -lpthread. Someone with expertise in the gtest phtread setup for elektra should probably take a look if there is a better way to handle this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need:

find_package(Threads)
and then you can add ${CMAKE_THREAD_LIBS_INIT} to linker flags

Are you sure it should be in COMMON_FLAGS?

Copy link
Contributor Author

@rautesamtr rautesamtr Jun 16, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

find_package(Threads)
and then you can add ${CMAKE_THREAD_LIBS_INIT} to linker flags

This is already used in LibAddTest and i still run into compiling issues. Adding it globally fixed them. Therefore the question if someone with expertise in this can solve this better.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My suggestion was to not directly use -lpthread (that is not portable), but to use ${CMAKE_THREAD_LIBS_INIT} instead. With the change we can merge the PR.

If -fsanitize=address generates code that requires to be linked with ${CMAKE_THREAD_LIBS_INIT} then we will have to do this, someone with more expertise will also not be able to change this fact.

If its needed can be found out by compiling and linking it. No expertise required here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe @mpranj has time to set up a new build job that uses clang with ENABLE_ASAN?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you say that it actually is not needed globally but only gtest suddenly does not link with ENABLE_ASAN? Then we should not enable it globally, but fix the linking order for the gtests.

We had a issue with pthread and gtest already here: #737

You can either find out the exact dependencies of every library and do a topological sort or you can simply guess and shuffle around the linker flags until it works (as done in #737)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do I understand this correctly: A new build job with ENABLE_ASAN is not needed any more?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it will be needed once i fix the linking granularity and this pr get merged.

Copy link
Contributor

@markus2330 markus2330 Jun 16, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly, the build job will be needed ;) The not needed referred to the global pthread linker flag ;) Let us use #160 in future to avoid such confusions.

It would also be interesting to have it before the PR is merged: we can trigger the build job from here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So i investigated this issue further and tried to solve it for gtest but that only moved the problem to the next library using pthread. This bug report explains this issue for gcc further. According to it, clang solves it by linking to pthread when -fsanitize=address is passed, gcc does not. So i propose to use the solution from the the bug report to pass-Wl,--as-needed ${CMAKE_THREAD_LIBS_INIT} as last compiler flag.

This adds the thread link with --as-needed when ASAN option is enabled
on gcc builds.

The if ENABLE_ASAN block was also moved below the GCC block so it gets
appended to both clang and gcc build in the same order.
@rautesamtr
Copy link
Contributor Author

jenkins build clang-asan please

ASAN needs to be linked before other things otherwis it produces the
following error message: `ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD.`
@markus2330
Copy link
Contributor

Looks good, everything builds now.

@rautesamtr
Copy link
Contributor Author

jenkins build clang-asan please

@rautesamtr
Copy link
Contributor Author

all but the clang-asan, but that will need some suppression files #788

@markus2330
Copy link
Contributor

@raetiacorvus Thanks, great job! I merged it because clang with ENABLE_DEBUG is broken and ENABLE_ASAN seems like a very nice solution!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Provide cmake option to compile with address sanitizer gir does not build with clang sanitizer
3 participants