AddressSanitizer: Properly handle dispatch_source_set_cancel_handler with a
authorKuba Brecka <kuba.brecka@gmail.com>
Mon, 22 Dec 2014 17:30:04 +0000 (17:30 +0000)
committerKuba Brecka <kuba.brecka@gmail.com>
Mon, 22 Dec 2014 17:30:04 +0000 (17:30 +0000)
NULL handler

Per
https://developer.apple.com/library/mac/documentation/Performance/Reference/GCD_libdispatch_Ref/index.html,
the dispatch_source_set_cancel_handler() API *can* be called with a NULL
handler. In that case, the libdispatch removes an already existing cancellation
handler, if there was one. ASan's interceptor always creates a new block that
always tries to call the original handler. In case the original block is NULL,
a segmentation fault happens. Let's fix that by not wrapping a NULL-block at
all.

It looks like all the other libdispatch APIs (which we intercept) do *not*
allow NULL. So it's really only the dispatch_source_set_cancel_handler one that
needs this fix.

Reviewed at http://reviews.llvm.org/D6747

llvm-svn: 224711

compiler-rt/lib/asan/asan_mac.cc

index ae0fa15..0d43953 100644 (file)
@@ -403,6 +403,10 @@ INTERCEPTOR(void, dispatch_after,
 
 INTERCEPTOR(void, dispatch_source_set_cancel_handler,
             dispatch_source_t ds, void(^work)(void)) {
+  if (!work) {
+    REAL(dispatch_source_set_cancel_handler)(ds, work);
+    return;
+  }
   ENABLE_FRAME_POINTER;
   GET_ASAN_BLOCK(work);
   REAL(dispatch_source_set_cancel_handler)(ds, asan_block);