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 437c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainarvoid InitializePlatformInterceptors() {} 4431f78fda9c511f9ab4afc3494f54cb24450e28e6Alexander Potapenko 4538dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonovbool PlatformHasDifferentMemcpyAndMemmove() { 4638dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov // On OS X 10.7 memcpy() and memmove() are both resolved 4738dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov // into memmove$VARIANT$sse42. 4838dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov // See also http://code.google.com/p/address-sanitizer/issues/detail?id=34. 4938dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov // TODO(glider): need to check dynamically that memcpy() and memmove() are 5038dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov // actually the same function. 5138dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov return GetMacosVersion() == MACOS_VERSION_SNOW_LEOPARD; 5238dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov} 5338dd4ed885e714c376466f6fe0d69f5f22d37014Alexey Samsonov 54eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenkoextern "C" 55eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenkovoid __asan_init(); 56eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko 57eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenkostatic const char kDyldInsertLibraries[] = "DYLD_INSERT_LIBRARIES"; 58fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander PotapenkoLowLevelAllocator allocator_for_env; 59fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko 60fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko// Change the value of the env var |name|, leaking the original value. 61fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko// If |name_value| is NULL, the variable is deleted from the environment, 62fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko// otherwise the corresponding "NAME=value" string is replaced with 63fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko// |name_value|. 64fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenkovoid LeakyResetEnv(const char *name, const char *name_value) { 65fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko char ***env_ptr = _NSGetEnviron(); 66fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko CHECK(env_ptr); 67fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko char **environ = *env_ptr; 68fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko CHECK(environ); 69fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko uptr name_len = internal_strlen(name); 70fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko while (*environ != 0) { 71fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko uptr len = internal_strlen(*environ); 72fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko if (len > name_len) { 73fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko const char *p = *environ; 74fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko if (!internal_memcmp(p, name, name_len) && p[name_len] == '=') { 75fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko // Match. 76fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko if (name_value) { 77fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko // Replace the old value with the new one. 78fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko *environ = const_cast<char*>(name_value); 79fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko } else { 80fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko // Shift the subsequent pointers back. 81fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko char **del = environ; 82fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko do { 83fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko del[0] = del[1]; 84366984e3aa286f7b4fb45f5c9e703f2768c407edKostya Serebryany } while (*del++); 85fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko } 86fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko } 87fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko } 88fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko environ++; 89fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko } 90fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko} 91eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko 9286277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesstatic bool reexec_disabled = false; 9386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 9486277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesvoid DisableReexec() { 9586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines reexec_disabled = true; 9686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines} 9786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 98eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenkovoid MaybeReexec() { 9986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (reexec_disabled) return; 10086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 10169563986ca570ce750111a82264d51ddbf4107baAlexander Potapenko // Make sure the dynamic ASan runtime library is preloaded so that the 10269563986ca570ce750111a82264d51ddbf4107baAlexander Potapenko // wrappers work. If it is not, set DYLD_INSERT_LIBRARIES and re-exec 10369563986ca570ce750111a82264d51ddbf4107baAlexander Potapenko // ourselves. 104eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko Dl_info info; 1054ea14c2fa243684e1d7a017bd4f0d1e38801de0aAlexey Samsonov CHECK(dladdr((void*)((uptr)__asan_init), &info)); 106fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko char *dyld_insert_libraries = 107fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko const_cast<char*>(GetEnv(kDyldInsertLibraries)); 108180e988700858a838e00fe9406f170502c203b85Alexey Samsonov uptr old_env_len = dyld_insert_libraries ? 109fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko internal_strlen(dyld_insert_libraries) : 0; 110e6b91fdad54c4c9a711b5149d65ea6a6f368d9abAlexey Samsonov uptr fname_len = internal_strlen(info.dli_fname); 11186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines const char *dylib_name = StripModuleName(info.dli_fname); 11286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines uptr dylib_name_len = internal_strlen(dylib_name); 113eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko if (!dyld_insert_libraries || 11486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines !REAL(strstr)(dyld_insert_libraries, dylib_name)) { 115eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko // DYLD_INSERT_LIBRARIES is not set or does not contain the runtime 116eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko // library. 117eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko char program_name[1024]; 118eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko uint32_t buf_size = sizeof(program_name); 119eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko _NSGetExecutablePath(program_name, &buf_size); 120fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko char *new_env = const_cast<char*>(info.dli_fname); 121eb5f427c10c5d23e520def5f921cbbed831526beAlexander Potapenko if (dyld_insert_libraries) { 122eb5f427c10c5d23e520def5f921cbbed831526beAlexander Potapenko // Append the runtime dylib name to the existing value of 123eb5f427c10c5d23e520def5f921cbbed831526beAlexander Potapenko // DYLD_INSERT_LIBRARIES. 124fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko new_env = (char*)allocator_for_env.Allocate(old_env_len + fname_len + 2); 125eb5f427c10c5d23e520def5f921cbbed831526beAlexander Potapenko internal_strncpy(new_env, dyld_insert_libraries, old_env_len); 126eb5f427c10c5d23e520def5f921cbbed831526beAlexander Potapenko new_env[old_env_len] = ':'; 127eb5f427c10c5d23e520def5f921cbbed831526beAlexander Potapenko // Copy fname_len and add a trailing zero. 1288da17ea3bc3ba0a28844642921247a3b9a1a3bcdKostya Serebryany internal_strncpy(new_env + old_env_len + 1, info.dli_fname, 1298da17ea3bc3ba0a28844642921247a3b9a1a3bcdKostya Serebryany fname_len + 1); 130fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko // Ok to use setenv() since the wrappers don't depend on the value of 131fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko // asan_inited. 132eb5f427c10c5d23e520def5f921cbbed831526beAlexander Potapenko setenv(kDyldInsertLibraries, new_env, /*overwrite*/1); 133eb5f427c10c5d23e520def5f921cbbed831526beAlexander Potapenko } else { 134eb5f427c10c5d23e520def5f921cbbed831526beAlexander Potapenko // Set DYLD_INSERT_LIBRARIES equal to the runtime dylib name. 135eb5f427c10c5d23e520def5f921cbbed831526beAlexander Potapenko setenv(kDyldInsertLibraries, info.dli_fname, /*overwrite*/0); 136eb5f427c10c5d23e520def5f921cbbed831526beAlexander Potapenko } 1372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(1, "exec()-ing the program with\n"); 1382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(1, "%s=%s\n", kDyldInsertLibraries, new_env); 1392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(1, "to enable ASan wrappers.\n"); 140eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko execv(program_name, *_NSGetArgv()); 14186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 14286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // We get here only if execv() failed. 14386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines Report("ERROR: The process is launched without DYLD_INSERT_LIBRARIES, " 14486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines "which is required for ASan to work. ASan tried to set the " 14586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines "environment variable and re-execute itself, but execv() failed, " 14686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines "possibly because of sandbox restrictions. Make sure to launch the " 14786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines "executable with:\n%s=%s\n", kDyldInsertLibraries, new_env); 14886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines CHECK("execv failed" && 0); 14986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 15086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 15186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // DYLD_INSERT_LIBRARIES is set and contains the runtime library. Let's remove 15286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // the dylib from the environment variable, because interceptors are installed 15386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // and we don't want our children to inherit the variable. 15486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 15586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines uptr env_name_len = internal_strlen(kDyldInsertLibraries); 15686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // Allocate memory to hold the previous env var name, its value, the '=' 15786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // sign and the '\0' char. 15886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines char *new_env = (char*)allocator_for_env.Allocate( 15986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines old_env_len + 2 + env_name_len); 16086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines CHECK(new_env); 16186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines internal_memset(new_env, '\0', old_env_len + 2 + env_name_len); 16286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines internal_strncpy(new_env, kDyldInsertLibraries, env_name_len); 16386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines new_env[env_name_len] = '='; 16486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines char *new_env_pos = new_env + env_name_len + 1; 16586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 16686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // Iterate over colon-separated pieces of |dyld_insert_libraries|. 16786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines char *piece_start = dyld_insert_libraries; 16886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines char *piece_end = NULL; 16986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines char *old_env_end = dyld_insert_libraries + old_env_len; 17086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines do { 17186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (piece_start[0] == ':') piece_start++; 17286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines piece_end = REAL(strchr)(piece_start, ':'); 17386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (!piece_end) piece_end = dyld_insert_libraries + old_env_len; 17486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if ((uptr)(piece_start - dyld_insert_libraries) > old_env_len) break; 17586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines uptr piece_len = piece_end - piece_start; 17686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 17786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines char *filename_start = 17886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines (char *)internal_memrchr(piece_start, '/', piece_len); 17986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines uptr filename_len = piece_len; 18086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (filename_start) { 18186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines filename_start += 1; 18286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines filename_len = piece_len - (filename_start - piece_start); 183fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko } else { 18486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines filename_start = piece_start; 185fe984cc9d8aa86cf6d5aa802b223a588d6f14105Alexander Potapenko } 18686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 18786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // If the current piece isn't the runtime library name, 18886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // append it to new_env. 18986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if ((dylib_name_len != filename_len) || 19086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines (internal_memcmp(filename_start, dylib_name, dylib_name_len) != 0)) { 19186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (new_env_pos != new_env + env_name_len + 1) { 19286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines new_env_pos[0] = ':'; 19386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines new_env_pos++; 19486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 19586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines internal_strncpy(new_env_pos, piece_start, piece_len); 19686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines new_env_pos += piece_len; 19786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 19886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // Move on to the next piece. 19986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines piece_start = piece_end; 20086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } while (piece_start < old_env_end); 20186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines 20286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // Can't use setenv() here, because it requires the allocator to be 20386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // initialized. 20486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // FIXME: instead of filtering DYLD_INSERT_LIBRARIES here, do it in 20586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines // a separate function called after InitializeAllocator(). 20686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (new_env_pos == new_env + env_name_len + 1) new_env = NULL; 20786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines LeakyResetEnv(kDyldInsertLibraries, new_env); 208eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko} 209eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko 2101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// No-op. Mac does not support static linkage anyway. 2111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *AsanDoesNotSupportStaticLinkage() { 2123f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryany return 0; 2131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// No-op. Mac does not support static linkage anyway. 2162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid AsanCheckDynamicRTPrereqs() {} 2172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 2182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// No-op. Mac does not support static linkage anyway. 2192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid AsanCheckIncompatibleRT() {} 2202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 22175b19ebf25af204cf209d108997272822241d6daAlexander Potapenkovoid AsanPlatformThreadInit() { 22275b19ebf25af204cf209d108997272822241d6daAlexander Potapenko} 22375b19ebf25af204cf209d108997272822241d6daAlexander Potapenko 22457db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonovvoid ReadContextStack(void *context, uptr *stack, uptr *ssize) { 225f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov UNIMPLEMENTED(); 226f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov} 227f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov 2281e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Support for the following functions from libdispatch on Mac OS: 2291e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_async_f() 2301e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_async() 2311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_sync_f() 2321e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_sync() 2331e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_after_f() 2341e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_after() 2351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_group_async_f() 2361e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_group_async() 2371e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// TODO(glider): libdispatch API contains other functions that we don't support 2381e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// yet. 2391e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 2401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_sync() and dispatch_sync_f() are synchronous, although chances are 2411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// they can cause jobs to run on a thread different from the current one. 2421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// TODO(glider): if so, we need a test for this (otherwise we should remove 2431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// them). 2441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 2451e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The following functions use dispatch_barrier_async_f() (which isn't a library 2461e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// function but is exported) and are thus supported: 2471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_source_set_cancel_handler_f() 2481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_source_set_cancel_handler() 2491e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_source_set_event_handler_f() 2501e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// dispatch_source_set_event_handler() 2511e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 2521e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The reference manual for Grand Central Dispatch is available at 2531e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// http://developer.apple.com/library/mac/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html 2541e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The implementation details are at 2551e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// http://libdispatch.macosforge.org/trac/browser/trunk/src/queue.c 2561e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 257f7ceaad2919d2e26e9edea29232bc9dd8f145c42Alexey Samsonovtypedef void* dispatch_group_t; 258f7ceaad2919d2e26e9edea29232bc9dd8f145c42Alexey Samsonovtypedef void* dispatch_queue_t; 259af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenkotypedef void* dispatch_source_t; 260ee3925515e4c7966f3ef489f687aa7e5692806a9Kostya Serebryanytypedef u64 dispatch_time_t; 261f7ceaad2919d2e26e9edea29232bc9dd8f145c42Alexey Samsonovtypedef void (*dispatch_function_t)(void *block); 2625cf832dc0a6566ae4bb8d48b1f41da623d2c2c1aAlexey Samsonovtypedef void* (*worker_t)(void *block); 2635cf832dc0a6566ae4bb8d48b1f41da623d2c2c1aAlexey Samsonov 2645cf832dc0a6566ae4bb8d48b1f41da623d2c2c1aAlexey Samsonov// A wrapper for the ObjC blocks used to support libdispatch. 2655cf832dc0a6566ae4bb8d48b1f41da623d2c2c1aAlexey Samsonovtypedef struct { 2665cf832dc0a6566ae4bb8d48b1f41da623d2c2c1aAlexey Samsonov void *block; 2675cf832dc0a6566ae4bb8d48b1f41da623d2c2c1aAlexey Samsonov dispatch_function_t func; 268e0cff0bc20ae51790c8edfbceb817e18ebf5355eKostya Serebryany u32 parent_tid; 2695cf832dc0a6566ae4bb8d48b1f41da623d2c2c1aAlexey Samsonov} asan_block_context_t; 2705cf832dc0a6566ae4bb8d48b1f41da623d2c2c1aAlexey Samsonov 271b157c67e17c3fc8805c8b7cb590668885680608fTimur IskhodzhanovALWAYS_INLINE 272c3390df6670cb166119b961eb27a033fb9073496Kostya Serebryanyvoid asan_register_worker_thread(int parent_tid, StackTrace *stack) { 273c25e62b0cdbca855e7611583b0ff7013c31db21dAlexey Samsonov AsanThread *t = GetCurrentThread(); 274af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko if (!t) { 27586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines t = AsanThread::Create(/* start_routine */ nullptr, /* arg */ nullptr, 27686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines parent_tid, stack, /* detached */ true); 277af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko t->Init(); 278def1be9b7ef4091ce465c0fbfb26cdb52128ade8Alexey Samsonov asanThreadRegistry().StartThread(t->tid(), 0, 0); 279c25e62b0cdbca855e7611583b0ff7013c31db21dAlexey Samsonov SetCurrentThread(t); 280af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko } 281af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko} 282af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko 2832483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko// For use by only those functions that allocated the context via 2842483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko// alloc_asan_context(). 2851e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern "C" 2861e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid asan_dispatch_call_block_and_release(void *block) { 287a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany GET_STACK_TRACE_THREAD; 2881e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_block_context_t *context = (asan_block_context_t*)block; 2892d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines VReport(2, 2902d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines "asan_dispatch_call_block_and_release(): " 2912d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines "context: %p, pthread_self: %p\n", 2922d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines block, pthread_self()); 293af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko asan_register_worker_thread(context->parent_tid, &stack); 2941e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // Call the original dispatcher for the block. 2951e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany context->func(context->block); 296fe6d91684bcda766593800f6307233f1a33d31f6Kostya Serebryany asan_free(context, &stack, FROM_MALLOC); 2971e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 2981e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 2991e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} // namespace __asan 3001e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 3011e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyusing namespace __asan; // NOLINT 3021e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 3031e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Wrap |ctxt| and |func| into an asan_block_context_t. 3041e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The caller retains control of the allocated context. 3051e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyextern "C" 3061e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyasan_block_context_t *alloc_asan_context(void *ctxt, dispatch_function_t func, 3076d1862363c88c183b0ed7740fca876342cf0474bStephen Hines BufferedStackTrace *stack) { 3081e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_block_context_t *asan_ctxt = 3091e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany (asan_block_context_t*) asan_malloc(sizeof(asan_block_context_t), stack); 3101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_ctxt->block = ctxt; 3111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_ctxt->func = func; 312c25e62b0cdbca855e7611583b0ff7013c31db21dAlexey Samsonov asan_ctxt->parent_tid = GetCurrentTidOrInvalid(); 3131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany return asan_ctxt; 3141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 3151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 316b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko// Define interceptor for dispatch_*_f function with the three most common 317b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko// parameters: dispatch_queue_t, context, dispatch_function_t. 318b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko#define INTERCEPT_DISPATCH_X_F_3(dispatch_x_f) \ 319b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko INTERCEPTOR(void, dispatch_x_f, dispatch_queue_t dq, void *ctxt, \ 320b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko dispatch_function_t func) { \ 321a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany GET_STACK_TRACE_THREAD; \ 322b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); \ 32386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (Verbosity() >= 2) { \ 324b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko Report(#dispatch_x_f "(): context: %p, pthread_self: %p\n", \ 325b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko asan_ctxt, pthread_self()); \ 3262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines PRINT_CURRENT_STACK(); \ 3272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } \ 3282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return REAL(dispatch_x_f)(dq, (void*)asan_ctxt, \ 3292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines asan_dispatch_call_block_and_release); \ 3300ffc227f91b068c78908f735a4846f92e339a337Kostya Serebryany } 331b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander Potapenko 332b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander PotapenkoINTERCEPT_DISPATCH_X_F_3(dispatch_async_f) 333b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander PotapenkoINTERCEPT_DISPATCH_X_F_3(dispatch_sync_f) 334b09dd34786713a150fed5c5ab1529f01de0e2bc0Alexander PotapenkoINTERCEPT_DISPATCH_X_F_3(dispatch_barrier_async_f) 3351e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 336f2598fc21bf651d23feab396a7581d48c01c3be5Alexey SamsonovINTERCEPTOR(void, dispatch_after_f, dispatch_time_t when, 337f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov dispatch_queue_t dq, void *ctxt, 338f2598fc21bf651d23feab396a7581d48c01c3be5Alexey Samsonov dispatch_function_t func) { 339a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany GET_STACK_TRACE_THREAD; 3401e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); 34186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (Verbosity() >= 2) { 3421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany Report("dispatch_after_f: %p\n", asan_ctxt); 3431e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany PRINT_CURRENT_STACK(); 3441e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany } 34509672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov return REAL(dispatch_after_f)(when, dq, (void*)asan_ctxt, 34609672caefb5694f1981a1712fdefa44840a95e67Alexey Samsonov asan_dispatch_call_block_and_release); 3471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 3481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 349af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander PotapenkoINTERCEPTOR(void, dispatch_group_async_f, dispatch_group_t group, 350af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko dispatch_queue_t dq, void *ctxt, 351af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko dispatch_function_t func) { 352a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany GET_STACK_TRACE_THREAD; 353af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); 35486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (Verbosity() >= 2) { 355af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko Report("dispatch_group_async_f(): context: %p, pthread_self: %p\n", 356af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko asan_ctxt, pthread_self()); 357af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko PRINT_CURRENT_STACK(); 358af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko } 359af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko REAL(dispatch_group_async_f)(group, dq, (void*)asan_ctxt, 360af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko asan_dispatch_call_block_and_release); 361af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko} 362af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko 36369563986ca570ce750111a82264d51ddbf4107baAlexander Potapenko#if !defined(MISSING_BLOCKS_SUPPORT) 364af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenkoextern "C" { 365af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenkovoid dispatch_async(dispatch_queue_t dq, void(^work)(void)); 366af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenkovoid dispatch_group_async(dispatch_group_t dg, dispatch_queue_t dq, 367af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko void(^work)(void)); 368af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenkovoid dispatch_after(dispatch_time_t when, dispatch_queue_t queue, 369af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko void(^work)(void)); 370af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenkovoid dispatch_source_set_cancel_handler(dispatch_source_t ds, 371af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko void(^work)(void)); 372af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenkovoid dispatch_source_set_event_handler(dispatch_source_t ds, void(^work)(void)); 3732483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko} 3742483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko 375af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko#define GET_ASAN_BLOCK(work) \ 376af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko void (^asan_block)(void); \ 377c25e62b0cdbca855e7611583b0ff7013c31db21dAlexey Samsonov int parent_tid = GetCurrentTidOrInvalid(); \ 378af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko asan_block = ^(void) { \ 379a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany GET_STACK_TRACE_THREAD; \ 380af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko asan_register_worker_thread(parent_tid, &stack); \ 381af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko work(); \ 3822483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko } 3832483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko 3842483ce3e635515d907c0cd8c97db315142fb28dbAlexander PotapenkoINTERCEPTOR(void, dispatch_async, 385af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko dispatch_queue_t dq, void(^work)(void)) { 3866a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines ENABLE_FRAME_POINTER; 387af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko GET_ASAN_BLOCK(work); 388af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko REAL(dispatch_async)(dq, asan_block); 389af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko} 390af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko 391af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander PotapenkoINTERCEPTOR(void, dispatch_group_async, 392af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko dispatch_group_t dg, dispatch_queue_t dq, void(^work)(void)) { 3936a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines ENABLE_FRAME_POINTER; 394af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko GET_ASAN_BLOCK(work); 395af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko REAL(dispatch_group_async)(dg, dq, asan_block); 3962483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko} 3972483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko 3982483ce3e635515d907c0cd8c97db315142fb28dbAlexander PotapenkoINTERCEPTOR(void, dispatch_after, 399af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko dispatch_time_t when, dispatch_queue_t queue, void(^work)(void)) { 4006a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines ENABLE_FRAME_POINTER; 401af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko GET_ASAN_BLOCK(work); 402af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko REAL(dispatch_after)(when, queue, asan_block); 4032483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko} 4042483ce3e635515d907c0cd8c97db315142fb28dbAlexander Potapenko 405af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander PotapenkoINTERCEPTOR(void, dispatch_source_set_cancel_handler, 406af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko dispatch_source_t ds, void(^work)(void)) { 40786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines if (!work) { 40886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines REAL(dispatch_source_set_cancel_handler)(ds, work); 40986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines return; 41086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines } 4116a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines ENABLE_FRAME_POINTER; 412af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko GET_ASAN_BLOCK(work); 413af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko REAL(dispatch_source_set_cancel_handler)(ds, asan_block); 4141e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 4151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 416af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander PotapenkoINTERCEPTOR(void, dispatch_source_set_event_handler, 417af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko dispatch_source_t ds, void(^work)(void)) { 4186a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines ENABLE_FRAME_POINTER; 419af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko GET_ASAN_BLOCK(work); 420af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko REAL(dispatch_source_set_event_handler)(ds, asan_block); 421af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko} 422af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko#endif 423af198e421ea198c5f9fa8cd691aa9a209b3d96a0Alexander Potapenko 424649a270f5341efe9c57f473dbb78706b0b2ed523Alexey Samsonov#endif // SANITIZER_MAC 425