Skip to content

Commit a9ed31b

Browse files
committed
[Asan][Darwin][GCD] Add interceptor for dispatch_mach_create_f
When enabling DriverKit, Address Sanitizer was unable to intercept thread creation directly for dispatch workerthreads. Because of this calls to GetStackTraceFromID failed and ASan was unable to capture a meaningful stack trace. This patch adds an interceptor for a dispatch function as a proxy that is "close enough" to thread creation so that ASan is able to meaningfully capture and register the dispatched thread. Note: I propose not adding a test for this change. Because this change is only meaningful in such a narrow usecase on Darwin and is incredibly difficult to add a meaningful test. rdar://108021828 Differential Revision: https://reviews.llvm.org/D154753
1 parent 1bb54d5 commit a9ed31b

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed

compiler-rt/lib/asan/asan_mac.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,18 @@ typedef void* dispatch_source_t;
136136
typedef u64 dispatch_time_t;
137137
typedef void (*dispatch_function_t)(void *block);
138138
typedef void* (*worker_t)(void *block);
139+
typedef unsigned long dispatch_mach_reason;
140+
typedef void *dispatch_mach_msg_t;
141+
typedef int mach_error_t;
142+
typedef void *dispatch_mach_t;
143+
144+
typedef void (*dispatch_mach_handler_function_t)(void *context,
145+
dispatch_mach_reason reason,
146+
dispatch_mach_msg_t message,
147+
mach_error_t error);
148+
typedef void (^dispatch_mach_handler_t)(dispatch_mach_reason reason,
149+
dispatch_mach_msg_t message,
150+
mach_error_t error);
139151

140152
// A wrapper for the ObjC blocks used to support libdispatch.
141153
typedef struct {
@@ -247,6 +259,8 @@ void dispatch_after(dispatch_time_t when, dispatch_queue_t queue,
247259
void dispatch_source_set_cancel_handler(dispatch_source_t ds,
248260
void(^work)(void));
249261
void dispatch_source_set_event_handler(dispatch_source_t ds, void(^work)(void));
262+
dispatch_mach_t dispatch_mach_create(const char *label, dispatch_queue_t queue,
263+
dispatch_mach_handler_t handler);
250264
}
251265

252266
#define GET_ASAN_BLOCK(work) \
@@ -296,6 +310,34 @@ INTERCEPTOR(void, dispatch_source_set_event_handler,
296310
GET_ASAN_BLOCK(work);
297311
REAL(dispatch_source_set_event_handler)(ds, asan_block);
298312
}
313+
314+
INTERCEPTOR(void *, dispatch_mach_create, const char *label,
315+
dispatch_queue_t dq, dispatch_mach_handler_t handler) {
316+
int parent_tid = GetCurrentTidOrInvalid();
317+
return REAL(dispatch_mach_create)(
318+
label, dq,
319+
^(dispatch_mach_reason reason, dispatch_mach_msg_t message,
320+
mach_error_t error) {
321+
GET_STACK_TRACE_THREAD;
322+
asan_register_worker_thread(parent_tid, &stack);
323+
handler(reason, message, error);
324+
});
325+
}
326+
327+
INTERCEPTOR(void *, dispatch_mach_create_f, const char *label,
328+
dispatch_queue_t dq, void *ctxt,
329+
dispatch_mach_handler_function_t handler) {
330+
int parent_tid = GetCurrentTidOrInvalid();
331+
return REAL(dispatch_mach_create)(
332+
label, dq,
333+
^(dispatch_mach_reason reason, dispatch_mach_msg_t message,
334+
mach_error_t error) {
335+
GET_STACK_TRACE_THREAD;
336+
asan_register_worker_thread(parent_tid, &stack);
337+
handler(ctxt, reason, message, error);
338+
});
339+
}
340+
299341
#endif
300342

301343
#endif // SANITIZER_APPLE

0 commit comments

Comments
 (0)