asan_mac.cc revision a874fe5b5d67152e4e737498d532eec80940bdcd
11e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===-- asan_mac.cc -------------------------------------------------------===// 21e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 31e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The LLVM Compiler Infrastructure 41e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 51e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is distributed under the University of Illinois Open Source 61e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// License. See LICENSE.TXT for details. 71e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 81e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===// 91e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is a part of AddressSanitizer, an address sanity checker. 111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Mac-specific details. 131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===// 141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 15d6567c5166412f6acdde851e767c26f332d51d3dKostya Serebryany#ifdef __APPLE__ 161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_mac.h" 181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_internal.h" 201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_stack.h" 211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_thread.h" 221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_thread_registry.h" 231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <sys/mman.h> 25a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany#include <fcntl.h> 261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <unistd.h> 271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 281957399c5d44802939021d5b89b8171719d96b75Kostya Serebryany#include <new> 294f24d3efb98fcf2b4d667bd42a4d840dbab0ce82Kostya Serebryany 301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanynamespace __asan { 311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern dispatch_async_f_f real_dispatch_async_f; 331e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern dispatch_sync_f_f real_dispatch_sync_f; 341e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern dispatch_after_f_f real_dispatch_after_f; 351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern dispatch_barrier_async_f_f real_dispatch_barrier_async_f; 361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern dispatch_group_async_f_f real_dispatch_group_async_f; 371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern pthread_workqueue_additem_np_f real_pthread_workqueue_additem_np; 381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// No-op. Mac does not support static linkage anyway. 401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *AsanDoesNotSupportStaticLinkage() { 411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return NULL; 421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 44a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryanystatic void *asan_mmap(void *addr, size_t length, int prot, int flags, 451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany int fd, uint64_t offset) { 461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return mmap(addr, length, prot, flags, fd, offset); 471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 49a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryanyssize_t AsanWrite(int fd, const void *buf, size_t count) { 501e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return write(fd, buf, count); 511e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 53de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryanyvoid *AsanMmapSomewhereOrDie(size_t size, const char *mem_type) { 54de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany size = RoundUpTo(size, kPageSize); 55de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany void *res = asan_mmap(0, size, 56de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany PROT_READ | PROT_WRITE, 57de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany MAP_PRIVATE | MAP_ANON, -1, 0); 58de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany if (res == (void*)-1) { 59de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany OutOfMemoryMessageAndDie(mem_type, size); 60de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany } 61de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany return res; 62de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany} 63de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany 64a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryanyvoid *AsanMmapFixedNoReserve(uintptr_t fixed_addr, size_t size) { 65a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany return asan_mmap((void*)fixed_addr, size, 66a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany PROT_READ | PROT_WRITE, 67a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE, 68a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany 0, 0); 69a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany} 70a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany 71a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryanyvoid *AsanMmapFixedReserve(uintptr_t fixed_addr, size_t size) { 72a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany return asan_mmap((void*)fixed_addr, size, 73a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany PROT_READ | PROT_WRITE, 74a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany MAP_PRIVATE | MAP_ANON | MAP_FIXED, 75a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany 0, 0); 76a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany} 77a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany 78a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryanyvoid *AsanMprotect(uintptr_t fixed_addr, size_t size) { 79a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany return asan_mmap((void*)fixed_addr, size, 80a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany PROT_NONE, 81a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE, 82a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany 0, 0); 83a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany} 84a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany 85de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryanyvoid AsanUnmapOrDie(void *addr, size_t size) { 86de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany if (!addr || !size) return; 87de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany int res = munmap(addr, size); 88de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany if (res != 0) { 89de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany Report("Failed to unmap\n"); 90de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany ASAN_DIE; 91de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany } 92de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany} 93de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany 94de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryanyint AsanOpenReadonly(const char* filename) { 95de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany return open(filename, O_RDONLY); 96de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany} 97de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany 98de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryanyssize_t AsanRead(int fd, void *buf, size_t count) { 99de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany return read(fd, buf, count); 100de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany} 101de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany 102de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryanyint AsanClose(int fd) { 103de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany return close(fd); 104de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany} 105de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany 1061e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Support for the following functions from libdispatch on Mac OS: 1071e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_async_f() 1081e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_async() 1091e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_sync_f() 1101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_sync() 1111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_after_f() 1121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_after() 1131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_group_async_f() 1141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_group_async() 1151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// TODO(glider): libdispatch API contains other functions that we don't support 1161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// yet. 1171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 1181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_sync() and dispatch_sync_f() are synchronous, although chances are 1191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// they can cause jobs to run on a thread different from the current one. 1201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// TODO(glider): if so, we need a test for this (otherwise we should remove 1211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// them). 1221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 1231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The following functions use dispatch_barrier_async_f() (which isn't a library 1241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// function but is exported) and are thus supported: 1251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_source_set_cancel_handler_f() 1261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_source_set_cancel_handler() 1271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_source_set_event_handler_f() 1281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_source_set_event_handler() 1291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 1301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The reference manual for Grand Central Dispatch is available at 1311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// http://developer.apple.com/library/mac/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html 1321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The implementation details are at 1331e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// http://libdispatch.macosforge.org/trac/browser/trunk/src/queue.c 1341e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern "C" 1361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid asan_dispatch_call_block_and_release(void *block) { 1371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany GET_STACK_TRACE_HERE(kStackTraceMax, /*fast_unwind*/false); 1381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_block_context_t *context = (asan_block_context_t*)block; 1391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_v >= 2) { 1401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany Report("asan_dispatch_call_block_and_release(): " 1411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany "context: %p, pthread_self: %p\n", 1421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany block, pthread_self()); 1431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 1441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany AsanThread *t = asanThreadRegistry().GetCurrent(); 1451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (t) { 1461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // We've already executed a job on this worker thread. Let's reuse the 1471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // AsanThread object. 1481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (t != asanThreadRegistry().GetMain()) { 1491e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // Flush the statistics and update the current thread's tid. 1501e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asanThreadRegistry().UnregisterThread(t); 1511e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asanThreadRegistry().RegisterThread(t, context->parent_tid, &stack); 1521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 1531e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // Otherwise the worker is being executed on the main thread -- we are 1541e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // draining the dispatch queue. 1551e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // TODO(glider): any checks for that? 1561e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } else { 1571e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // It's incorrect to assert that the current thread is not dying: at least 1581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // the callbacks from dispatch_sync() are sometimes called after the TSD is 1591e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // destroyed. 1601e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany t = (AsanThread*)asan_malloc(sizeof(AsanThread), &stack); 1611e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany new(t) AsanThread(context->parent_tid, 1621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany /*start_routine*/NULL, /*arg*/NULL, &stack); 16369eca73ac96688c8bfe1f23ee006af29c7858c40Kostya Serebryany t->Init(); 1641e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asanThreadRegistry().SetCurrent(t); 1651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 1661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // Call the original dispatcher for the block. 1671e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany context->func(context->block); 1681e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_free(context, &stack); 1691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 1701e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1711e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} // namespace __asan 1721e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1731e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyusing namespace __asan; // NOLINT 1741e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1751e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Wrap |ctxt| and |func| into an asan_block_context_t. 1761e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The caller retains control of the allocated context. 1771e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern "C" 1781e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyasan_block_context_t *alloc_asan_context(void *ctxt, dispatch_function_t func, 1791e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany AsanStackTrace *stack) { 1801e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_block_context_t *asan_ctxt = 1811e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany (asan_block_context_t*) asan_malloc(sizeof(asan_block_context_t), stack); 1821e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_ctxt->block = ctxt; 1831e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_ctxt->func = func; 1841e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany AsanThread *curr_thread = asanThreadRegistry().GetCurrent(); 1851e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_debug) { 1861e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // Sometimes at Chromium teardown this assertion is violated: 1871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // -- a task is created via dispatch_async() on the "CFMachPort" 1881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // thread while doing _dispatch_queue_drain(); 1891e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // -- a task is created via dispatch_async_f() on the 1901e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // "com.apple.root.default-overcommit-priority" thread while doing 1911e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // _dispatch_dispose(). 1921e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // TODO(glider): find out what's going on. 1931e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany CHECK(curr_thread || asanThreadRegistry().IsCurrentThreadDying()); 1941e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 1951e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_ctxt->parent_tid = asanThreadRegistry().GetCurrentTidOrMinusOne(); 1961e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return asan_ctxt; 1971e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 1981e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1991e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// TODO(glider): can we reduce code duplication by introducing a macro? 2001e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern "C" 2011e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyint WRAP(dispatch_async_f)(dispatch_queue_t dq, 2021e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany void *ctxt, 2031e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany dispatch_function_t func) { 2041e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany GET_STACK_TRACE_HERE(kStackTraceMax, /*fast_unwind*/false); 2051e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); 2061e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_v >= 2) { 2071e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany Report("dispatch_async_f(): context: %p, pthread_self: %p\n", 2081e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_ctxt, pthread_self()); 2091e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany PRINT_CURRENT_STACK(); 2101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 2111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return real_dispatch_async_f(dq, (void*)asan_ctxt, 2121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_dispatch_call_block_and_release); 2131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern "C" 2161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyint WRAP(dispatch_sync_f)(dispatch_queue_t dq, 2171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany void *ctxt, 2181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany dispatch_function_t func) { 2191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany GET_STACK_TRACE_HERE(kStackTraceMax, /*fast_unwind*/false); 2201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); 2211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_v >= 2) { 2221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany Report("dispatch_sync_f(): context: %p, pthread_self: %p\n", 2231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_ctxt, pthread_self()); 2241e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany PRINT_CURRENT_STACK(); 2251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 2261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return real_dispatch_sync_f(dq, (void*)asan_ctxt, 2271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_dispatch_call_block_and_release); 2281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern "C" 2311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyint WRAP(dispatch_after_f)(dispatch_time_t when, 2321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany dispatch_queue_t dq, 2331e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany void *ctxt, 2341e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany dispatch_function_t func) { 2351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany GET_STACK_TRACE_HERE(kStackTraceMax, /*fast_unwind*/false); 2361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); 2371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_v >= 2) { 2381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany Report("dispatch_after_f: %p\n", asan_ctxt); 2391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany PRINT_CURRENT_STACK(); 2401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 2411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return real_dispatch_after_f(when, dq, (void*)asan_ctxt, 2421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_dispatch_call_block_and_release); 2431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern "C" 2461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid WRAP(dispatch_barrier_async_f)(dispatch_queue_t dq, 2471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany void *ctxt, dispatch_function_t func) { 2481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany GET_STACK_TRACE_HERE(kStackTraceMax, /*fast_unwind*/false); 2491e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); 2501e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_v >= 2) { 2511e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany Report("dispatch_barrier_async_f(): context: %p, pthread_self: %p\n", 2521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_ctxt, pthread_self()); 2531e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany PRINT_CURRENT_STACK(); 2541e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 2551e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany real_dispatch_barrier_async_f(dq, (void*)asan_ctxt, 2561e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_dispatch_call_block_and_release); 2571e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2591e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern "C" 2601e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid WRAP(dispatch_group_async_f)(dispatch_group_t group, 2611e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany dispatch_queue_t dq, 2621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany void *ctxt, dispatch_function_t func) { 2631e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany GET_STACK_TRACE_HERE(kStackTraceMax, /*fast_unwind*/false); 2641e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); 2651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_v >= 2) { 2661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany Report("dispatch_group_async_f(): context: %p, pthread_self: %p\n", 2671e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_ctxt, pthread_self()); 2681e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany PRINT_CURRENT_STACK(); 2691e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 2701e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany real_dispatch_group_async_f(group, dq, (void*)asan_ctxt, 2711e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_dispatch_call_block_and_release); 2721e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2731e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2741e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The following stuff has been extremely helpful while looking for the 2751e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// unhandled functions that spawned jobs on Chromium shutdown. If the verbosity 2761e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// level is 2 or greater, we wrap pthread_workqueue_additem_np() in order to 2771e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// find the points of worker thread creation (each of such threads may be used 2781e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// to run several tasks, that's why this is not enough to support the whole 2791e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// libdispatch API. 2801e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern "C" 2811e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *wrap_workitem_func(void *arg) { 2821e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_v >= 2) { 2831e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany Report("wrap_workitem_func: %p, pthread_self: %p\n", arg, pthread_self()); 2841e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 2851e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_block_context_t *ctxt = (asan_block_context_t*)arg; 2861e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany worker_t fn = (worker_t)(ctxt->func); 2871e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany void *result = fn(ctxt->block); 2881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany GET_STACK_TRACE_HERE(kStackTraceMax, /*fast_unwind*/false); 2891e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_free(arg, &stack); 2901e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return result; 2911e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2921e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2931e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern "C" 2941e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyint WRAP(pthread_workqueue_additem_np)(pthread_workqueue_t workq, 2951e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany void *(*workitem_func)(void *), void * workitem_arg, 2961e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany pthread_workitem_handle_t * itemhandlep, unsigned int *gencountp) { 2971e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany GET_STACK_TRACE_HERE(kStackTraceMax, /*fast_unwind*/false); 2981e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_block_context_t *asan_ctxt = 2991e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany (asan_block_context_t*) asan_malloc(sizeof(asan_block_context_t), &stack); 3001e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_ctxt->block = workitem_arg; 3011e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_ctxt->func = (dispatch_function_t)workitem_func; 3021e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_ctxt->parent_tid = asanThreadRegistry().GetCurrentTidOrMinusOne(); 3031e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany if (FLAG_v >= 2) { 3041e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany Report("pthread_workqueue_additem_np: %p\n", asan_ctxt); 3051e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany PRINT_CURRENT_STACK(); 3061e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 3071e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return real_pthread_workqueue_additem_np(workq, wrap_workitem_func, asan_ctxt, 3081e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany itemhandlep, gencountp); 3091e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 310d6567c5166412f6acdde851e767c26f332d51d3dKostya Serebryany 311d6567c5166412f6acdde851e767c26f332d51d3dKostya Serebryany#endif // __APPLE__ 312