asan_mac.cc revision 86277eb844c4983c81de62d7c050e92fe7155788
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 1524e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov#include "sanitizer_common/sanitizer_platform.h" 1630e110edf92303237d471f1cb8e3ad07954fb145Evgeniy Stepanov#if SANITIZER_MAC 171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 1864ce2db7c838cd95315f7a4428e8a628eaa3e2fcAlexey Samsonov#include "asan_interceptors.h" 191e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_internal.h" 20895b3872acb5bcccb1769ea69d37dd33c722f99dAlexander Potapenko#include "asan_mapping.h" 211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_stack.h" 221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_thread.h" 2331f78fda9c511f9ab4afc3494f54cb24450e28e6Alexander Potapenko#include "sanitizer_common/sanitizer_atomic.h" 24ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov#include "sanitizer_common/sanitizer_libc.h" 252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "sanitizer_common/sanitizer_mac.h" 261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 27eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko#include <crt_externs.h> // for _NSGetArgv 28eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko#include <dlfcn.h> // for dladdr() 298a34d384255f9bf4c2a9b03a4df81b9af57124d8Alexander Potapenko#include <mach-o/dyld.h> 309b993e8cd0f8964782ee93524603d0c53adc2249Kostya Serebryany#include <mach-o/loader.h> 311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <sys/mman.h> 32ef14ff6512d7b2e20aa3206dff820b5f90285420Kostya Serebryany#include <sys/resource.h> 3359dc578df0de177b44c8c78f69d73735e38e5c14Alexander Potapenko#include <sys/sysctl.h> 349107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany#include <sys/ucontext.h> 35a874fe5b5d67152e4e737498d532eec80940bdcdKostya Serebryany#include <fcntl.h> 36e205a9daec9ec4afed956cf5455889725b9192fbAlexander Potapenko#include <pthread.h> 37e205a9daec9ec4afed956cf5455889725b9192fbAlexander Potapenko#include <stdlib.h> // for free() 381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <unistd.h> 39d55f5f8c413622db4bd28b5cca9bfeb4d61564e0Kostya Serebryany#include <libkern/OSAtomic.h> 401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanynamespace __asan { 421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 433f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryanyvoid GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { 449107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany ucontext_t *ucontext = (ucontext_t*)context; 455af39e50366f1aacbebc284f572f08ad1ad07357Kostya Serebryany# if SANITIZER_WORDSIZE == 64 469107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany *pc = ucontext->uc_mcontext->__ss.__rip; 479107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany *bp = ucontext->uc_mcontext->__ss.__rbp; 489107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany *sp = ucontext->uc_mcontext->__ss.__rsp; 499107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany# else 509107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany *pc = ucontext->uc_mcontext->__ss.__eip; 519107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany *bp = ucontext->uc_mcontext->__ss.__ebp; 529107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany *sp = ucontext->uc_mcontext->__ss.__esp; 535af39e50366f1aacbebc284f572f08ad1ad07357Kostya Serebryany# endif // SANITIZER_WORDSIZE 549107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany} 559107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany 5631f78fda9c511f9ab4afc3494f54cb24450e28e6Alexander Potapenko 5738dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonovbool PlatformHasDifferentMemcpyAndMemmove() { 5838dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov // On OS X 10.7 memcpy() and memmove() are both resolved 5938dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov // into memmove$VARIANT$sse42. 6038dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov // See also http://code.google.com/p/address-sanitizer/issues/detail?id=34. 6138dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov // TODO(glider): need to check dynamically that memcpy() and memmove() are 6238dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov // actually the same function. 6338dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov return GetMacosVersion() == MACOS_VERSION_SNOW_LEOPARD; 6438dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov} 6538dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov 66eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenkoextern "C" 67eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenkovoid __asan_init(); 68eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko 69eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenkostatic const char kDyldInsertLibraries[] = "DYLD_INSERT_LIBRARIES"; 70fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander PotapenkoLowLevelAllocator allocator_for_env; 71fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko 72fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko// Change the value of the env var |name|, leaking the original value. 73fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko// If |name_value| is NULL, the variable is deleted from the environment, 74fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko// otherwise the corresponding "NAME=value" string is replaced with 75fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko// |name_value|. 76fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenkovoid LeakyResetEnv(const char *name, const char *name_value) { 77fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko char ***env_ptr = _NSGetEnviron(); 78fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko CHECK(env_ptr); 79fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko char **environ = *env_ptr; 80fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko CHECK(environ); 81fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko uptr name_len = internal_strlen(name); 82fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko while (*environ != 0) { 83fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko uptr len = internal_strlen(*environ); 84fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko if (len > name_len) { 85fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko const char *p = *environ; 86fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko if (!internal_memcmp(p, name, name_len) && p[name_len] == '=') { 87fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko // Match. 88fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko if (name_value) { 89fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko // Replace the old value with the new one. 90fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko *environ = const_cast<char*>(name_value); 91fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko } else { 92fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko // Shift the subsequent pointers back. 93fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko char **del = environ; 94fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko do { 95fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko del[0] = del[1]; 96366984e3aa286f7b4fb45f5c9e703f2768c407edKostya Serebryany } while (*del++); 97fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko } 98fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko } 99fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko } 100fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko environ++; 101fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko } 102fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko} 103eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko 10486277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesstatic bool reexec_disabled = false; 10586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 10686277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesvoid DisableReexec() { 10786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines reexec_disabled = true; 10886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines} 10986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 110eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenkovoid MaybeReexec() { 11186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (reexec_disabled) return; 11286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 11369563986ca570ce750111a82264d51ddbf4107baAlexander Potapenko // Make sure the dynamic ASan runtime library is preloaded so that the 11469563986ca570ce750111a82264d51ddbf4107baAlexander Potapenko // wrappers work. If it is not, set DYLD_INSERT_LIBRARIES and re-exec 11569563986ca570ce750111a82264d51ddbf4107baAlexander Potapenko // ourselves. 116eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko Dl_info info; 1174ea14c2fa243684e1d7a017bd4f0d1e38801de0aAlexey Samsonov CHECK(dladdr((void*)((uptr)__asan_init), &info)); 118fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko char *dyld_insert_libraries = 119fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko const_cast<char*>(GetEnv(kDyldInsertLibraries)); 120180e988700858a838e00fe9406f170502c203b85Alexey Samsonov uptr old_env_len = dyld_insert_libraries ? 121fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko internal_strlen(dyld_insert_libraries) : 0; 122e6b91fdad54c4c9a711b5149d65ea6a6f368d9abAlexey Samsonov uptr fname_len = internal_strlen(info.dli_fname); 12386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines const char *dylib_name = StripModuleName(info.dli_fname); 12486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines uptr dylib_name_len = internal_strlen(dylib_name); 125eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko if (!dyld_insert_libraries || 12686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines !REAL(strstr)(dyld_insert_libraries, dylib_name)) { 127eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko // DYLD_INSERT_LIBRARIES is not set or does not contain the runtime 128eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko // library. 129eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko char program_name[1024]; 130eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko uint32_t buf_size = sizeof(program_name); 131eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko _NSGetExecutablePath(program_name, &buf_size); 132fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko char *new_env = const_cast<char*>(info.dli_fname); 133eb5f427c10c5d23e520def5f921cbbed831526beAlexander Potapenko if (dyld_insert_libraries) { 134eb5f427c10c5d23e520def5f921cbbed831526beAlexander Potapenko // Append the runtime dylib name to the existing value of 135eb5f427c10c5d23e520def5f921cbbed831526beAlexander Potapenko // DYLD_INSERT_LIBRARIES. 136fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko new_env = (char*)allocator_for_env.Allocate(old_env_len + fname_len + 2); 137eb5f427c10c5d23e520def5f921cbbed831526beAlexander Potapenko internal_strncpy(new_env, dyld_insert_libraries, old_env_len); 138eb5f427c10c5d23e520def5f921cbbed831526beAlexander Potapenko new_env[old_env_len] = ':'; 139eb5f427c10c5d23e520def5f921cbbed831526beAlexander Potapenko // Copy fname_len and add a trailing zero. 1408da17ea3bc3ba0a28844642921247a3b9a1a3bcdKostya Serebryany internal_strncpy(new_env + old_env_len + 1, info.dli_fname, 1418da17ea3bc3ba0a28844642921247a3b9a1a3bcdKostya Serebryany fname_len + 1); 142fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko // Ok to use setenv() since the wrappers don't depend on the value of 143fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko // asan_inited. 144eb5f427c10c5d23e520def5f921cbbed831526beAlexander Potapenko setenv(kDyldInsertLibraries, new_env, /*overwrite*/1); 145eb5f427c10c5d23e520def5f921cbbed831526beAlexander Potapenko } else { 146eb5f427c10c5d23e520def5f921cbbed831526beAlexander Potapenko // Set DYLD_INSERT_LIBRARIES equal to the runtime dylib name. 147eb5f427c10c5d23e520def5f921cbbed831526beAlexander Potapenko setenv(kDyldInsertLibraries, info.dli_fname, /*overwrite*/0); 148eb5f427c10c5d23e520def5f921cbbed831526beAlexander Potapenko } 1492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(1, "exec()-ing the program with\n"); 1502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(1, "%s=%s\n", kDyldInsertLibraries, new_env); 1512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(1, "to enable ASan wrappers.\n"); 152eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko execv(program_name, *_NSGetArgv()); 15386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 15486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // We get here only if execv() failed. 15586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines Report("ERROR: The process is launched without DYLD_INSERT_LIBRARIES, " 15686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines "which is required for ASan to work. ASan tried to set the " 15786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines "environment variable and re-execute itself, but execv() failed, " 15886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines "possibly because of sandbox restrictions. Make sure to launch the " 15986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines "executable with:\n%s=%s\n", kDyldInsertLibraries, new_env); 16086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines CHECK("execv failed" && 0); 16186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 16286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 16386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // DYLD_INSERT_LIBRARIES is set and contains the runtime library. Let's remove 16486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // the dylib from the environment variable, because interceptors are installed 16586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // and we don't want our children to inherit the variable. 16686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 16786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines uptr env_name_len = internal_strlen(kDyldInsertLibraries); 16886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // Allocate memory to hold the previous env var name, its value, the '=' 16986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // sign and the '\0' char. 17086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines char *new_env = (char*)allocator_for_env.Allocate( 17186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines old_env_len + 2 + env_name_len); 17286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines CHECK(new_env); 17386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines internal_memset(new_env, '\0', old_env_len + 2 + env_name_len); 17486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines internal_strncpy(new_env, kDyldInsertLibraries, env_name_len); 17586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines new_env[env_name_len] = '='; 17686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines char *new_env_pos = new_env + env_name_len + 1; 17786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 17886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // Iterate over colon-separated pieces of |dyld_insert_libraries|. 17986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines char *piece_start = dyld_insert_libraries; 18086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines char *piece_end = NULL; 18186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines char *old_env_end = dyld_insert_libraries + old_env_len; 18286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines do { 18386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (piece_start[0] == ':') piece_start++; 18486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines piece_end = REAL(strchr)(piece_start, ':'); 18586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (!piece_end) piece_end = dyld_insert_libraries + old_env_len; 18686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if ((uptr)(piece_start - dyld_insert_libraries) > old_env_len) break; 18786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines uptr piece_len = piece_end - piece_start; 18886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 18986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines char *filename_start = 19086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines (char *)internal_memrchr(piece_start, '/', piece_len); 19186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines uptr filename_len = piece_len; 19286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (filename_start) { 19386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines filename_start += 1; 19486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines filename_len = piece_len - (filename_start - piece_start); 195fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko } else { 19686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines filename_start = piece_start; 197fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko } 19886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 19986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // If the current piece isn't the runtime library name, 20086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // append it to new_env. 20186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if ((dylib_name_len != filename_len) || 20286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines (internal_memcmp(filename_start, dylib_name, dylib_name_len) != 0)) { 20386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (new_env_pos != new_env + env_name_len + 1) { 20486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines new_env_pos[0] = ':'; 20586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines new_env_pos++; 20686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 20786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines internal_strncpy(new_env_pos, piece_start, piece_len); 20886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines new_env_pos += piece_len; 20986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 21086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // Move on to the next piece. 21186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines piece_start = piece_end; 21286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } while (piece_start < old_env_end); 21386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 21486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // Can't use setenv() here, because it requires the allocator to be 21586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // initialized. 21686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // FIXME: instead of filtering DYLD_INSERT_LIBRARIES here, do it in 21786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // a separate function called after InitializeAllocator(). 21886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (new_env_pos == new_env + env_name_len + 1) new_env = NULL; 21986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines LeakyResetEnv(kDyldInsertLibraries, new_env); 220eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko} 221eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko 2221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// No-op. Mac does not support static linkage anyway. 2231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *AsanDoesNotSupportStaticLinkage() { 2243f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany return 0; 2251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// No-op. Mac does not support static linkage anyway. 2282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid AsanCheckDynamicRTPrereqs() {} 2292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 2302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// No-op. Mac does not support static linkage anyway. 2312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid AsanCheckIncompatibleRT() {} 2322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 23375b19ebf25af204cf209d108997272822241d6daAlexander Potapenkovoid AsanPlatformThreadInit() { 23475b19ebf25af204cf209d108997272822241d6daAlexander Potapenko} 23575b19ebf25af204cf209d108997272822241d6daAlexander Potapenko 23657db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonovvoid ReadContextStack(void *context, uptr *stack, uptr *ssize) { 237f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov UNIMPLEMENTED(); 238f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov} 239f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov 2401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Support for the following functions from libdispatch on Mac OS: 2411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_async_f() 2421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_async() 2431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_sync_f() 2441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_sync() 2451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_after_f() 2461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_after() 2471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_group_async_f() 2481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_group_async() 2491e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// TODO(glider): libdispatch API contains other functions that we don't support 2501e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// yet. 2511e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 2521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_sync() and dispatch_sync_f() are synchronous, although chances are 2531e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// they can cause jobs to run on a thread different from the current one. 2541e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// TODO(glider): if so, we need a test for this (otherwise we should remove 2551e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// them). 2561e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 2571e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The following functions use dispatch_barrier_async_f() (which isn't a library 2581e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// function but is exported) and are thus supported: 2591e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_source_set_cancel_handler_f() 2601e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_source_set_cancel_handler() 2611e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_source_set_event_handler_f() 2621e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_source_set_event_handler() 2631e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 2641e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The reference manual for Grand Central Dispatch is available at 2651e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// http://developer.apple.com/library/mac/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html 2661e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The implementation details are at 2671e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// http://libdispatch.macosforge.org/trac/browser/trunk/src/queue.c 2681e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 269f7ceaad2919d2e26e9edea29232bc9dd8f145c42Alexey Samsonovtypedef void* dispatch_group_t; 270f7ceaad2919d2e26e9edea29232bc9dd8f145c42Alexey Samsonovtypedef void* dispatch_queue_t; 271af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenkotypedef void* dispatch_source_t; 272ee3925515e4c7966f3ef489f687aa7e5692806a9Kostya Serebryanytypedef u64 dispatch_time_t; 273f7ceaad2919d2e26e9edea29232bc9dd8f145c42Alexey Samsonovtypedef void (*dispatch_function_t)(void *block); 2745cf832dc0a6566ae4bb8d48b1f41da623d2c2c1aAlexey Samsonovtypedef void* (*worker_t)(void *block); 2755cf832dc0a6566ae4bb8d48b1f41da623d2c2c1aAlexey Samsonov 2765cf832dc0a6566ae4bb8d48b1f41da623d2c2c1aAlexey Samsonov// A wrapper for the ObjC blocks used to support libdispatch. 2775cf832dc0a6566ae4bb8d48b1f41da623d2c2c1aAlexey Samsonovtypedef struct { 2785cf832dc0a6566ae4bb8d48b1f41da623d2c2c1aAlexey Samsonov void *block; 2795cf832dc0a6566ae4bb8d48b1f41da623d2c2c1aAlexey Samsonov dispatch_function_t func; 280e0cff0bc20ae51790c8edfbceb817e18ebf5355eKostya Serebryany u32 parent_tid; 2815cf832dc0a6566ae4bb8d48b1f41da623d2c2c1aAlexey Samsonov} asan_block_context_t; 2825cf832dc0a6566ae4bb8d48b1f41da623d2c2c1aAlexey Samsonov 283b157c67e17c3fc8805c8b7cb590668885680608fTimur IskhodzhanovALWAYS_INLINE 284c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryanyvoid asan_register_worker_thread(int parent_tid, StackTrace *stack) { 285c25e62b0cdbca855e7611583b0ff7013c31db21dAlexey Samsonov AsanThread *t = GetCurrentThread(); 286af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko if (!t) { 28786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines t = AsanThread::Create(/* start_routine */ nullptr, /* arg */ nullptr, 28886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines parent_tid, stack, /* detached */ true); 289af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko t->Init(); 290def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov asanThreadRegistry().StartThread(t->tid(), 0, 0); 291c25e62b0cdbca855e7611583b0ff7013c31db21dAlexey Samsonov SetCurrentThread(t); 292af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko } 293af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko} 294af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko 2952483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko// For use by only those functions that allocated the context via 2962483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko// alloc_asan_context(). 2971e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern "C" 2981e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid asan_dispatch_call_block_and_release(void *block) { 299a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany GET_STACK_TRACE_THREAD; 3001e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_block_context_t *context = (asan_block_context_t*)block; 3012d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(2, 3022d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines "asan_dispatch_call_block_and_release(): " 3032d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines "context: %p, pthread_self: %p\n", 3042d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines block, pthread_self()); 305af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko asan_register_worker_thread(context->parent_tid, &stack); 3061e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // Call the original dispatcher for the block. 3071e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany context->func(context->block); 308fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany asan_free(context, &stack, FROM_MALLOC); 3091e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 3101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 3111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} // namespace __asan 3121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 3131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyusing namespace __asan; // NOLINT 3141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 3151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Wrap |ctxt| and |func| into an asan_block_context_t. 3161e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The caller retains control of the allocated context. 3171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern "C" 3181e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyasan_block_context_t *alloc_asan_context(void *ctxt, dispatch_function_t func, 3196d1862363c88c183b0ed7740fca876342cf0474bStephen Hines BufferedStackTrace *stack) { 3201e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_block_context_t *asan_ctxt = 3211e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany (asan_block_context_t*) asan_malloc(sizeof(asan_block_context_t), stack); 3221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_ctxt->block = ctxt; 3231e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_ctxt->func = func; 324c25e62b0cdbca855e7611583b0ff7013c31db21dAlexey Samsonov asan_ctxt->parent_tid = GetCurrentTidOrInvalid(); 3251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return asan_ctxt; 3261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 3271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 328b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko// Define interceptor for dispatch_*_f function with the three most common 329b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko// parameters: dispatch_queue_t, context, dispatch_function_t. 330b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko#define INTERCEPT_DISPATCH_X_F_3(dispatch_x_f) \ 331b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko INTERCEPTOR(void, dispatch_x_f, dispatch_queue_t dq, void *ctxt, \ 332b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko dispatch_function_t func) { \ 333a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany GET_STACK_TRACE_THREAD; \ 334b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); \ 33586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (Verbosity() >= 2) { \ 336b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko Report(#dispatch_x_f "(): context: %p, pthread_self: %p\n", \ 337b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko asan_ctxt, pthread_self()); \ 3382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PRINT_CURRENT_STACK(); \ 3392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } \ 3402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return REAL(dispatch_x_f)(dq, (void*)asan_ctxt, \ 3412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines asan_dispatch_call_block_and_release); \ 3420ffc227f91b068c78908f735a4846f92e339a337Kostya Serebryany } 343b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko 344b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander PotapenkoINTERCEPT_DISPATCH_X_F_3(dispatch_async_f) 345b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander PotapenkoINTERCEPT_DISPATCH_X_F_3(dispatch_sync_f) 346b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander PotapenkoINTERCEPT_DISPATCH_X_F_3(dispatch_barrier_async_f) 3471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 348f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void, dispatch_after_f, dispatch_time_t when, 349f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov dispatch_queue_t dq, void *ctxt, 350f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov dispatch_function_t func) { 351a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany GET_STACK_TRACE_THREAD; 3521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); 35386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (Verbosity() >= 2) { 3541e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany Report("dispatch_after_f: %p\n", asan_ctxt); 3551e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany PRINT_CURRENT_STACK(); 3561e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 35709672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(dispatch_after_f)(when, dq, (void*)asan_ctxt, 35809672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov asan_dispatch_call_block_and_release); 3591e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 3601e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 361af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander PotapenkoINTERCEPTOR(void, dispatch_group_async_f, dispatch_group_t group, 362af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko dispatch_queue_t dq, void *ctxt, 363af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko dispatch_function_t func) { 364a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany GET_STACK_TRACE_THREAD; 365af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); 36686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (Verbosity() >= 2) { 367af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko Report("dispatch_group_async_f(): context: %p, pthread_self: %p\n", 368af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko asan_ctxt, pthread_self()); 369af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko PRINT_CURRENT_STACK(); 370af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko } 371af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko REAL(dispatch_group_async_f)(group, dq, (void*)asan_ctxt, 372af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko asan_dispatch_call_block_and_release); 373af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko} 374af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko 37569563986ca570ce750111a82264d51ddbf4107baAlexander Potapenko#if !defined(MISSING_BLOCKS_SUPPORT) 376af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenkoextern "C" { 377af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenkovoid dispatch_async(dispatch_queue_t dq, void(^work)(void)); 378af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenkovoid dispatch_group_async(dispatch_group_t dg, dispatch_queue_t dq, 379af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko void(^work)(void)); 380af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenkovoid dispatch_after(dispatch_time_t when, dispatch_queue_t queue, 381af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko void(^work)(void)); 382af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenkovoid dispatch_source_set_cancel_handler(dispatch_source_t ds, 383af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko void(^work)(void)); 384af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenkovoid dispatch_source_set_event_handler(dispatch_source_t ds, void(^work)(void)); 3852483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko} 3862483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko 387af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko#define GET_ASAN_BLOCK(work) \ 388af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko void (^asan_block)(void); \ 389c25e62b0cdbca855e7611583b0ff7013c31db21dAlexey Samsonov int parent_tid = GetCurrentTidOrInvalid(); \ 390af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko asan_block = ^(void) { \ 391a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany GET_STACK_TRACE_THREAD; \ 392af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko asan_register_worker_thread(parent_tid, &stack); \ 393af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko work(); \ 3942483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko } 3952483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko 3962483ce3e635515d907c0cd8c97db315142fb28dbAlexander PotapenkoINTERCEPTOR(void, dispatch_async, 397af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko dispatch_queue_t dq, void(^work)(void)) { 3986a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines ENABLE_FRAME_POINTER; 399af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko GET_ASAN_BLOCK(work); 400af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko REAL(dispatch_async)(dq, asan_block); 401af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko} 402af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko 403af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander PotapenkoINTERCEPTOR(void, dispatch_group_async, 404af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko dispatch_group_t dg, dispatch_queue_t dq, void(^work)(void)) { 4056a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines ENABLE_FRAME_POINTER; 406af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko GET_ASAN_BLOCK(work); 407af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko REAL(dispatch_group_async)(dg, dq, asan_block); 4082483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko} 4092483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko 4102483ce3e635515d907c0cd8c97db315142fb28dbAlexander PotapenkoINTERCEPTOR(void, dispatch_after, 411af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko dispatch_time_t when, dispatch_queue_t queue, void(^work)(void)) { 4126a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines ENABLE_FRAME_POINTER; 413af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko GET_ASAN_BLOCK(work); 414af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko REAL(dispatch_after)(when, queue, asan_block); 4152483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko} 4162483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko 417af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander PotapenkoINTERCEPTOR(void, dispatch_source_set_cancel_handler, 418af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko dispatch_source_t ds, void(^work)(void)) { 41986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (!work) { 42086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines REAL(dispatch_source_set_cancel_handler)(ds, work); 42186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return; 42286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 4236a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines ENABLE_FRAME_POINTER; 424af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko GET_ASAN_BLOCK(work); 425af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko REAL(dispatch_source_set_cancel_handler)(ds, asan_block); 4261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 4271e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 428af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander PotapenkoINTERCEPTOR(void, dispatch_source_set_event_handler, 429af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko dispatch_source_t ds, void(^work)(void)) { 4306a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines ENABLE_FRAME_POINTER; 431af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko GET_ASAN_BLOCK(work); 432af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko REAL(dispatch_source_set_event_handler)(ds, asan_block); 433af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko} 434af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko#endif 435af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko 436649a270f5341efe9c57f473dbb78706b0b2ed523Alexey Samsonov#endif // SANITIZER_MAC 437