[PATCH] D59526: [TSan][libdispatch] Avoid infinite recursion in dispatch_apply[_f] interceptors
Julian Lettner via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 18 17:55:06 PDT 2019
yln created this revision.
yln added reviewers: kubamracek, dcoughlin.
Herald added projects: Sanitizers, LLVM.
Herald added subscribers: llvm-commits, Sanitizers.
In libdispatch, dispatch_apply is implemented in terms of
dispatch_apply_f. Unfortunately, this means that we can't implement the
interceptor for dispatch_apply_f by forwarding to the dispatch_apply
interceptor.
In the interceptor dispatch_apply_f, we can't use WRAP(dispatch_apply).
WRAP(dispatch_apply) -> REAL(dispatch_apply_f). Requires duplication of
some setup code.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D59526
Files:
compiler-rt/lib/tsan/rtl/tsan_libdispatch.cc
Index: compiler-rt/lib/tsan/rtl/tsan_libdispatch.cc
===================================================================
--- compiler-rt/lib/tsan/rtl/tsan_libdispatch.cc
+++ compiler-rt/lib/tsan/rtl/tsan_libdispatch.cc
@@ -479,34 +479,54 @@
DISPATCH_NOESCAPE void (^block)(size_t)) {
SCOPED_TSAN_INTERCEPTOR(dispatch_apply, iterations, queue, block);
- void *parent_to_child_sync = nullptr;
- uptr parent_to_child_sync_uptr = (uptr)&parent_to_child_sync;
- void *child_to_parent_sync = nullptr;
- uptr child_to_parent_sync_uptr = (uptr)&child_to_parent_sync;
+ u8 sync1, sync2;
+ uptr parent_to_child_sync = (uptr)&sync1;
+ uptr child_to_parent_sync = (uptr)&sync2;
- Release(thr, pc, parent_to_child_sync_uptr);
+ Release(thr, pc, parent_to_child_sync);
void (^new_block)(size_t) = ^(size_t iteration) {
SCOPED_INTERCEPTOR_RAW(dispatch_apply);
- Acquire(thr, pc, parent_to_child_sync_uptr);
+ Acquire(thr, pc, parent_to_child_sync);
SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();
block(iteration);
SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();
- Release(thr, pc, child_to_parent_sync_uptr);
+ Release(thr, pc, child_to_parent_sync);
};
SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();
REAL(dispatch_apply)(iterations, queue, new_block);
SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();
- Acquire(thr, pc, child_to_parent_sync_uptr);
+ Acquire(thr, pc, child_to_parent_sync);
+}
+
+static void invoke_block_iteration(void *param, size_t iteration) {
+ auto block = (void (^)(size_t)) param;
+ block(iteration);
}
TSAN_INTERCEPTOR(void, dispatch_apply_f, size_t iterations,
dispatch_queue_t queue, void *context,
void (*work)(void *, size_t)) {
SCOPED_TSAN_INTERCEPTOR(dispatch_apply_f, iterations, queue, context, work);
+
+ // Unfortunately, we cannot delegate to dispatch_apply, since libdispatch
+ // implements dispatch_apply in terms of dispatch_apply_f.
+ u8 sync1, sync2;
+ uptr parent_to_child_sync = (uptr)&sync1;
+ uptr child_to_parent_sync = (uptr)&sync2;
+
+ Release(thr, pc, parent_to_child_sync);
void (^new_block)(size_t) = ^(size_t iteration) {
+ SCOPED_INTERCEPTOR_RAW(dispatch_apply_f);
+ Acquire(thr, pc, parent_to_child_sync);
+ SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();
work(context, iteration);
+ SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();
+ Release(thr, pc, child_to_parent_sync);
};
- WRAP(dispatch_apply)(iterations, queue, new_block);
+ SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();
+ REAL(dispatch_apply_f)(iterations, queue, new_block, invoke_block_iteration);
+ SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();
+ Acquire(thr, pc, child_to_parent_sync);
}
DECLARE_REAL_AND_INTERCEPTOR(void, free, void *ptr)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D59526.191220.patch
Type: text/x-patch
Size: 2801 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190319/41a99341/attachment.bin>
More information about the llvm-commits
mailing list