Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
I think we need magic similar to sanitizer_common_interceptors.inc - define TSAN_INTERCEPT_FOO depending on the platform, define or not define TSAN_INTERCEPTOR(foo, ...) depending on its value, and define TSAN_MAYBE_INTERCEPT(foo) to either TSAN_INTERCEPT(foo), or empty statement.
What does happen with the current code? Does the binary crash? Or it works but you don't want unnecessary interceptors in the binary?
That would be useful to understand to evaluate the change.
lib/tsan/rtl/tsan_interceptors.cc | ||
---|---|---|
108 ↗ | (On Diff #15324) | What's the point in defining these TSAN_INTERCEPT_MMAP64 macros? Looks like an unnecessary level of indirection. They are used exactly once, and now I need to modify 3 places in stead of 2 when working with an interceptor. |
What does happen with the current code? Does the binary crash? Or it works but you don't want unnecessary interceptors in the binary?
With the current code we fail on ThreadSanitizer-Unit :: unit/TsanUnitTest/Mman.CallocOverflow:
FATAL: ThreadSanitizer: failed to intercept __xstat
This is because running the test causes calling stat() the interceptor of which relies on __xstat() that does not exist on FreeBSD.
Removing dead interceptors from the binary is good, but the major point is that we do not define things that do not exist on FreeBSD so the compiler will let us know as soon as we're trying to refer them. Thus, with the __xstat() interceptor removed we have a compile-time error for the original stat() interceptor exposing the invalid dependency.
OK, makes sense. Now I noticed the change to stat interceptor that is very different from the bulk of the changes.
lib/tsan/rtl/tsan_interceptors.cc | ||
---|---|---|
108 ↗ | (On Diff #15324) |
Well, the idea is to control the presence of a given interceptor in a single place. For example, if we want mmap64() to be defined on MAC, then we can do it with a single-line change: #define TSAN_INTERCEPT_MMAP64 SANITIZER_LINUX || SANITIZER_MAC and it will affect both the presence of the interceptor's definition and its initialization in InitializeInterceptors() so no need to change them (even though the very macro is used only once indeed). In contrast, surrounding interceptors and their initializations with #if/#endif means we need to change two lines and also take special care to make sure the conditions for the interceptor itself and its initialization do match.
Sounds like the previous version? |
I am proposing something in between:
#if SANITIZER_LINUX
TSAN_INTERCEPTOR(int, epoll_create, int size) {
SCOPED_TSAN_INTERCEPTOR(epoll_create, size); int fd = REAL(epoll_create)(size); if (fd >= 0) FdPollCreate(thr, pc, fd); return fd;
}
#define TSAN_MAYBE_INTERCEPT_EPOLL_CREATE TSAN_INTERCEPT(epoll_create)
#else
#define TSAN_MAYBE_INTERCEPT_EPOLL_CREATE
#endif
void InitializeInterceptors() {
...
TSAN_MAYBE_INTERCEPT_EPOLL_CREATE;
The original version indeed has unnecessary duplication of information. And the current version has unnecessary dissipation of information -- I need to update 3 places to add an interceptor, and when I am looking at an interceptor I can't understand when it's enabled (TSAN_INTERCEPT_TMPFILE64 name is pointless and does not communicate any useful information to me).