Skip to content

Commit 0bf5ec2

Browse files
committedMar 30, 2017
[tsan] Add interceptor for xpc_connection_cancel to avoid false positives
TSan reports a false positive when using xpc_connection_cancel. We're missing a happens-before edge from xpc_connection_cancel to the event handler on the same connection. Differential Revision: https://reviews.llvm.org/D31475 llvm-svn: 299086
1 parent fe7e91b commit 0bf5ec2

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed
 

‎compiler-rt/lib/tsan/rtl/tsan_interceptors_mac.cc

+6
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,12 @@ TSAN_INTERCEPTOR(void, xpc_connection_send_message_with_reply,
281281
(connection, message, replyq, new_handler);
282282
}
283283

284+
TSAN_INTERCEPTOR(void, xpc_connection_cancel, xpc_connection_t connection) {
285+
SCOPED_TSAN_INTERCEPTOR(xpc_connection_cancel, connection);
286+
Release(thr, pc, (uptr)connection);
287+
REAL(xpc_connection_cancel)(connection);
288+
}
289+
284290
// On macOS, libc++ is always linked dynamically, so intercepting works the
285291
// usual way.
286292
#define STDCXX_INTERCEPTOR TSAN_INTERCEPTOR
+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: %clang_tsan %s -o %t -framework Foundation
2+
// RUN: %run %t 2>&1 | FileCheck %s
3+
4+
#import <Foundation/Foundation.h>
5+
#import <xpc/xpc.h>
6+
7+
long global;
8+
9+
int main(int argc, const char *argv[]) {
10+
fprintf(stderr, "Hello world.\n");
11+
12+
dispatch_queue_t server_q = dispatch_queue_create("server.queue", DISPATCH_QUEUE_CONCURRENT);
13+
xpc_connection_t server_conn = xpc_connection_create(NULL, server_q);
14+
15+
xpc_connection_set_event_handler(server_conn, ^(xpc_object_t client) {
16+
if (client == XPC_ERROR_CONNECTION_INTERRUPTED || client == XPC_ERROR_CONNECTION_INVALID) {
17+
global = 43;
18+
19+
dispatch_async(dispatch_get_main_queue(), ^{
20+
CFRunLoopStop(CFRunLoopGetCurrent());
21+
});
22+
}
23+
});
24+
xpc_connection_resume(server_conn);
25+
26+
global = 42;
27+
28+
xpc_connection_cancel(server_conn);
29+
30+
CFRunLoopRun();
31+
32+
fprintf(stderr, "Done.\n");
33+
}
34+
35+
// CHECK: Hello world.
36+
// CHECK-NOT: WARNING: ThreadSanitizer
37+
// CHECK: Done.

0 commit comments

Comments
 (0)
Please sign in to comment.