This is an archive of the discontinued LLVM Phabricator instance.

[tsan] Bring Dispatch support to Linux
AbandonedPublic

Authored by yln on Oct 11 2018, 2:45 PM.

Details

Summary

Right now, TSan supports libdispatch only on Darwin, but the library is available on Linux as well (as part of the Swift project). Let's make TSan intercept the libdispatch APIs and support it on Linux.

The patch introduces a new build output on Linux, clang_rt.tsan_libdispatch-x86_64.a (for x86), which is an optional static library. The normal build of TSan is not changed, but if you use libdispatch for a project, you should link this optional library in. The patch also removes the build-time dependency on dispatch.h and manually declared the APIs that are used.

Diff Detail

Event Timeline

kubamracek created this revision.Oct 11 2018, 2:45 PM
delcypher requested changes to this revision.Oct 11 2018, 3:47 PM

This looks very promising. However I have some minor nits and some concerns regarding the use of system header files.

lib/tsan/rtl/tsan_libdispatch.cc
1

This comment is out-of-date. The file name is different now.

12

This comment is out-of-date. This isn't mac specific anymore.

23

Should the Block.h include be here? I'm pretty sure that's not a standard header file on Linux.

25

Perhaps you could have a comment here explaining that these declarations are to avoid depending the libdispatch header files? If you think these stubs might be needed elsewhere we could also move them into their own header file.

25

I'm not sure if including system headers such as pthread.h, stdint.h and sys/types.h is a good idea.

In sanitizer_interals_defs.h there is this comment.

// For portability reasons we do not include stddef.h, stdint.h or any other
// system header, but we do need some basic types that are not defined
// in a portable way by the language itself.

this suggests to me that we probably should avoid including these headers files and instead use the equivalent definitions in the sanitizer's own internal header files.

211

It's not clear to me why TSAN_INTERCEPTOR has been replaced with several other macros. If TSAN_INTERCEPTOR doesn't work could we provide another macro in this file just to avoid repeating ourselves along with a comment briefly saying why TSAN_INTERCEPTOR doesn't work here?

787

Who is responsible for calling this function? I was expecting to see some code in TSan's init that checks if this function is available and then calls it if it is. However I can't see anything like that in this patch.

This revision now requires changes to proceed.Oct 11 2018, 3:47 PM

Is it possible to make it just part of tsan without introducing a separate static library? That would be more scalable and easier to use.

We already doing something similar in tsan_interceptors.cc. For example, we intercept some libc++ functions, but end user may not link in libc++ and it will all work because interceptors do dynamic dispatch and don't fail if a function is not resolved.
This would require calling all dispatch functions as REAL(dispatch_foo), but otherwise should work.

dvyukov added inline comments.Oct 12 2018, 3:20 AM
lib/tsan/rtl/tsan_libdispatch.cc
57

Do we need this? If we declare an interceptor for a function, then we can call REAL(dispatch_barrier) without declaring it separately.

Is it possible to make it just part of tsan without introducing a separate static library? That would be more scalable and easier to use.

We already doing something similar in tsan_interceptors.cc. For example, we intercept some libc++ functions, but end user may not link in libc++ and it will all work because interceptors do dynamic dispatch and don't fail if a function is not resolved.
This would require calling all dispatch functions as REAL(dispatch_foo), but otherwise should work.

The real problem here is -fblocks, which needs -lBlocksRuntime, and this dependency is implicitly generated by the compiler and I don't think there's a way to make it a weak dependency. I also don't want to rewrite this file to not use blocks as that's going to make everything much less readable. I'm open to suggestions, of course.

Don't we already have a separate clang_rt.tsan_cxx static library? I thought that's here specifically to break up the dependencies.

Is it possible to make it just part of tsan without introducing a separate static library? That would be more scalable and easier to use.

We already doing something similar in tsan_interceptors.cc. For example, we intercept some libc++ functions, but end user may not link in libc++ and it will all work because interceptors do dynamic dispatch and don't fail if a function is not resolved.
This would require calling all dispatch functions as REAL(dispatch_foo), but otherwise should work.

The real problem here is -fblocks, which needs -lBlocksRuntime, and this dependency is implicitly generated by the compiler and I don't think there's a way to make it a weak dependency. I also don't want to rewrite this file to not use blocks as that's going to make everything much less readable. I'm open to suggestions, of course.

Don't we already have a separate clang_rt.tsan_cxx static library? I thought that's here specifically to break up the dependencies.

I don't know/remember why we have clang_rt.tsan_cxx. But we have __cxa_guard_acquire interceptor in tsan_interceptors.cc so we handle optionally linked libc++ without that. And I hope that we at least link in clang_rt.tsan_cxx transparently for users.

Can we simply enable -lBlocksRuntime always with tsan? We already do this for -lrt -lpthread.

yln commandeered this revision.Mar 7 2019, 2:57 PM
yln abandoned this revision.
yln removed a reviewer: yln.

Proposed changes were implemented without adding a new library.

lib/tsan/rtl/tsan_libdispatch.cc