Home | History | Annotate | Download | only in asan
      1 //===-- asan_rtl.cc -------------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file is a part of AddressSanitizer, an address sanity checker.
     11 //
     12 // Main file of the ASan run-time library.
     13 //===----------------------------------------------------------------------===//
     14 #include "asan_activation.h"
     15 #include "asan_allocator.h"
     16 #include "asan_interceptors.h"
     17 #include "asan_interface_internal.h"
     18 #include "asan_internal.h"
     19 #include "asan_mapping.h"
     20 #include "asan_poisoning.h"
     21 #include "asan_report.h"
     22 #include "asan_stack.h"
     23 #include "asan_stats.h"
     24 #include "asan_suppressions.h"
     25 #include "asan_thread.h"
     26 #include "sanitizer_common/sanitizer_atomic.h"
     27 #include "sanitizer_common/sanitizer_flags.h"
     28 #include "sanitizer_common/sanitizer_libc.h"
     29 #include "sanitizer_common/sanitizer_symbolizer.h"
     30 #include "lsan/lsan_common.h"
     31 #include "ubsan/ubsan_init.h"
     32 #include "ubsan/ubsan_platform.h"
     33 
     34 int __asan_option_detect_stack_use_after_return;  // Global interface symbol.
     35 uptr *__asan_test_only_reported_buggy_pointer;  // Used only for testing asan.
     36 
     37 namespace __asan {
     38 
     39 uptr AsanMappingProfile[kAsanMappingProfileSize];
     40 
     41 static void AsanDie() {
     42   static atomic_uint32_t num_calls;
     43   if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) {
     44     // Don't die twice - run a busy loop.
     45     while (1) { }
     46   }
     47   if (flags()->sleep_before_dying) {
     48     Report("Sleeping for %d second(s)\n", flags()->sleep_before_dying);
     49     SleepForSeconds(flags()->sleep_before_dying);
     50   }
     51   if (flags()->unmap_shadow_on_exit) {
     52     if (kMidMemBeg) {
     53       UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg);
     54       UnmapOrDie((void*)kMidMemEnd, kHighShadowEnd - kMidMemEnd);
     55     } else {
     56       UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
     57     }
     58   }
     59   if (common_flags()->coverage)
     60     __sanitizer_cov_dump();
     61   if (flags()->abort_on_error)
     62     Abort();
     63   internal__exit(flags()->exitcode);
     64 }
     65 
     66 static void AsanCheckFailed(const char *file, int line, const char *cond,
     67                             u64 v1, u64 v2) {
     68   Report("AddressSanitizer CHECK failed: %s:%d \"%s\" (0x%zx, 0x%zx)\n", file,
     69          line, cond, (uptr)v1, (uptr)v2);
     70   // FIXME: check for infinite recursion without a thread-local counter here.
     71   PRINT_CURRENT_STACK_CHECK();
     72   Die();
     73 }
     74 
     75 // -------------------------- Globals --------------------- {{{1
     76 int asan_inited;
     77 bool asan_init_is_running;
     78 
     79 #if !ASAN_FIXED_MAPPING
     80 uptr kHighMemEnd, kMidMemBeg, kMidMemEnd;
     81 #endif
     82 
     83 // -------------------------- Misc ---------------- {{{1
     84 void ShowStatsAndAbort() {
     85   __asan_print_accumulated_stats();
     86   Die();
     87 }
     88 
     89 // ---------------------- mmap -------------------- {{{1
     90 // Reserve memory range [beg, end].
     91 // We need to use inclusive range because end+1 may not be representable.
     92 void ReserveShadowMemoryRange(uptr beg, uptr end) {
     93   CHECK_EQ((beg % GetPageSizeCached()), 0);
     94   CHECK_EQ(((end + 1) % GetPageSizeCached()), 0);
     95   uptr size = end - beg + 1;
     96   DecreaseTotalMmap(size);  // Don't count the shadow against mmap_limit_mb.
     97   void *res = MmapFixedNoReserve(beg, size);
     98   if (res != (void*)beg) {
     99     Report("ReserveShadowMemoryRange failed while trying to map 0x%zx bytes. "
    100            "Perhaps you're using ulimit -v\n", size);
    101     Abort();
    102   }
    103   if (common_flags()->no_huge_pages_for_shadow)
    104     NoHugePagesInRegion(beg, size);
    105   if (common_flags()->use_madv_dontdump)
    106     DontDumpShadowMemory(beg, size);
    107 }
    108 
    109 // --------------- LowLevelAllocateCallbac ---------- {{{1
    110 static void OnLowLevelAllocate(uptr ptr, uptr size) {
    111   PoisonShadow(ptr, size, kAsanInternalHeapMagic);
    112 }
    113 
    114 // -------------------------- Run-time entry ------------------- {{{1
    115 // exported functions
    116 #define ASAN_REPORT_ERROR(type, is_write, size)                     \
    117 extern "C" NOINLINE INTERFACE_ATTRIBUTE                             \
    118 void __asan_report_ ## type ## size(uptr addr) {                    \
    119   GET_CALLER_PC_BP_SP;                                              \
    120   __asan_report_error(pc, bp, sp, addr, is_write, size, 0);         \
    121 }                                                                   \
    122 extern "C" NOINLINE INTERFACE_ATTRIBUTE                             \
    123 void __asan_report_exp_ ## type ## size(uptr addr, u32 exp) {       \
    124   GET_CALLER_PC_BP_SP;                                              \
    125   __asan_report_error(pc, bp, sp, addr, is_write, size, exp);       \
    126 }
    127 
    128 ASAN_REPORT_ERROR(load, false, 1)
    129 ASAN_REPORT_ERROR(load, false, 2)
    130 ASAN_REPORT_ERROR(load, false, 4)
    131 ASAN_REPORT_ERROR(load, false, 8)
    132 ASAN_REPORT_ERROR(load, false, 16)
    133 ASAN_REPORT_ERROR(store, true, 1)
    134 ASAN_REPORT_ERROR(store, true, 2)
    135 ASAN_REPORT_ERROR(store, true, 4)
    136 ASAN_REPORT_ERROR(store, true, 8)
    137 ASAN_REPORT_ERROR(store, true, 16)
    138 
    139 #define ASAN_REPORT_ERROR_N(type, is_write)                    \
    140 extern "C" NOINLINE INTERFACE_ATTRIBUTE                        \
    141 void __asan_report_ ## type ## _n(uptr addr, uptr size) {      \
    142   GET_CALLER_PC_BP_SP;                                         \
    143   __asan_report_error(pc, bp, sp, addr, is_write, size, 0);    \
    144 }                                                              \
    145 extern "C" NOINLINE INTERFACE_ATTRIBUTE                        \
    146 void __asan_report_exp_ ## type ## _n(uptr addr, uptr size, u32 exp) {      \
    147   GET_CALLER_PC_BP_SP;                                                      \
    148   __asan_report_error(pc, bp, sp, addr, is_write, size, exp);               \
    149 }
    150 
    151 ASAN_REPORT_ERROR_N(load, false)
    152 ASAN_REPORT_ERROR_N(store, true)
    153 
    154 #define ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp_arg)        \
    155     uptr sp = MEM_TO_SHADOW(addr);                                             \
    156     uptr s = size <= SHADOW_GRANULARITY ? *reinterpret_cast<u8 *>(sp)          \
    157                                         : *reinterpret_cast<u16 *>(sp);        \
    158     if (UNLIKELY(s)) {                                                         \
    159       if (UNLIKELY(size >= SHADOW_GRANULARITY ||                               \
    160                    ((s8)((addr & (SHADOW_GRANULARITY - 1)) + size - 1)) >=     \
    161                        (s8)s)) {                                               \
    162         if (__asan_test_only_reported_buggy_pointer) {                         \
    163           *__asan_test_only_reported_buggy_pointer = addr;                     \
    164         } else {                                                               \
    165           GET_CALLER_PC_BP_SP;                                                 \
    166           __asan_report_error(pc, bp, sp, addr, is_write, size, exp_arg);      \
    167         }                                                                      \
    168       }                                                                        \
    169     }
    170 
    171 #define ASAN_MEMORY_ACCESS_CALLBACK(type, is_write, size)                      \
    172   extern "C" NOINLINE INTERFACE_ATTRIBUTE                                      \
    173   void __asan_##type##size(uptr addr) {                                        \
    174     ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, 0)                  \
    175   }                                                                            \
    176   extern "C" NOINLINE INTERFACE_ATTRIBUTE                                      \
    177   void __asan_exp_##type##size(uptr addr, u32 exp) {                           \
    178     ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp)                \
    179   }
    180 
    181 ASAN_MEMORY_ACCESS_CALLBACK(load, false, 1)
    182 ASAN_MEMORY_ACCESS_CALLBACK(load, false, 2)
    183 ASAN_MEMORY_ACCESS_CALLBACK(load, false, 4)
    184 ASAN_MEMORY_ACCESS_CALLBACK(load, false, 8)
    185 ASAN_MEMORY_ACCESS_CALLBACK(load, false, 16)
    186 ASAN_MEMORY_ACCESS_CALLBACK(store, true, 1)
    187 ASAN_MEMORY_ACCESS_CALLBACK(store, true, 2)
    188 ASAN_MEMORY_ACCESS_CALLBACK(store, true, 4)
    189 ASAN_MEMORY_ACCESS_CALLBACK(store, true, 8)
    190 ASAN_MEMORY_ACCESS_CALLBACK(store, true, 16)
    191 
    192 extern "C"
    193 NOINLINE INTERFACE_ATTRIBUTE
    194 void __asan_loadN(uptr addr, uptr size) {
    195   if (__asan_region_is_poisoned(addr, size)) {
    196     GET_CALLER_PC_BP_SP;
    197     __asan_report_error(pc, bp, sp, addr, false, size, 0);
    198   }
    199 }
    200 
    201 extern "C"
    202 NOINLINE INTERFACE_ATTRIBUTE
    203 void __asan_exp_loadN(uptr addr, uptr size, u32 exp) {
    204   if (__asan_region_is_poisoned(addr, size)) {
    205     GET_CALLER_PC_BP_SP;
    206     __asan_report_error(pc, bp, sp, addr, false, size, exp);
    207   }
    208 }
    209 
    210 extern "C"
    211 NOINLINE INTERFACE_ATTRIBUTE
    212 void __asan_storeN(uptr addr, uptr size) {
    213   if (__asan_region_is_poisoned(addr, size)) {
    214     GET_CALLER_PC_BP_SP;
    215     __asan_report_error(pc, bp, sp, addr, true, size, 0);
    216   }
    217 }
    218 
    219 extern "C"
    220 NOINLINE INTERFACE_ATTRIBUTE
    221 void __asan_exp_storeN(uptr addr, uptr size, u32 exp) {
    222   if (__asan_region_is_poisoned(addr, size)) {
    223     GET_CALLER_PC_BP_SP;
    224     __asan_report_error(pc, bp, sp, addr, true, size, exp);
    225   }
    226 }
    227 
    228 // Force the linker to keep the symbols for various ASan interface functions.
    229 // We want to keep those in the executable in order to let the instrumented
    230 // dynamic libraries access the symbol even if it is not used by the executable
    231 // itself. This should help if the build system is removing dead code at link
    232 // time.
    233 static NOINLINE void force_interface_symbols() {
    234   volatile int fake_condition = 0;  // prevent dead condition elimination.
    235   // __asan_report_* functions are noreturn, so we need a switch to prevent
    236   // the compiler from removing any of them.
    237   switch (fake_condition) {
    238     case 1: __asan_report_load1(0); break;
    239     case 2: __asan_report_load2(0); break;
    240     case 3: __asan_report_load4(0); break;
    241     case 4: __asan_report_load8(0); break;
    242     case 5: __asan_report_load16(0); break;
    243     case 6: __asan_report_load_n(0, 0); break;
    244     case 7: __asan_report_store1(0); break;
    245     case 8: __asan_report_store2(0); break;
    246     case 9: __asan_report_store4(0); break;
    247     case 10: __asan_report_store8(0); break;
    248     case 11: __asan_report_store16(0); break;
    249     case 12: __asan_report_store_n(0, 0); break;
    250     case 13: __asan_report_exp_load1(0, 0); break;
    251     case 14: __asan_report_exp_load2(0, 0); break;
    252     case 15: __asan_report_exp_load4(0, 0); break;
    253     case 16: __asan_report_exp_load8(0, 0); break;
    254     case 17: __asan_report_exp_load16(0, 0); break;
    255     case 18: __asan_report_exp_load_n(0, 0, 0); break;
    256     case 19: __asan_report_exp_store1(0, 0); break;
    257     case 20: __asan_report_exp_store2(0, 0); break;
    258     case 21: __asan_report_exp_store4(0, 0); break;
    259     case 22: __asan_report_exp_store8(0, 0); break;
    260     case 23: __asan_report_exp_store16(0, 0); break;
    261     case 24: __asan_report_exp_store_n(0, 0, 0); break;
    262     case 25: __asan_register_globals(0, 0); break;
    263     case 26: __asan_unregister_globals(0, 0); break;
    264     case 27: __asan_set_death_callback(0); break;
    265     case 28: __asan_set_error_report_callback(0); break;
    266     case 29: __asan_handle_no_return(); break;
    267     case 30: __asan_address_is_poisoned(0); break;
    268     case 31: __asan_poison_memory_region(0, 0); break;
    269     case 32: __asan_unpoison_memory_region(0, 0); break;
    270     case 33: __asan_set_error_exit_code(0); break;
    271     case 34: __asan_before_dynamic_init(0); break;
    272     case 35: __asan_after_dynamic_init(); break;
    273     case 36: __asan_poison_stack_memory(0, 0); break;
    274     case 37: __asan_unpoison_stack_memory(0, 0); break;
    275     case 38: __asan_region_is_poisoned(0, 0); break;
    276     case 39: __asan_describe_address(0); break;
    277   }
    278 }
    279 
    280 static void asan_atexit() {
    281   Printf("AddressSanitizer exit stats:\n");
    282   __asan_print_accumulated_stats();
    283   // Print AsanMappingProfile.
    284   for (uptr i = 0; i < kAsanMappingProfileSize; i++) {
    285     if (AsanMappingProfile[i] == 0) continue;
    286     Printf("asan_mapping.h:%zd -- %zd\n", i, AsanMappingProfile[i]);
    287   }
    288 }
    289 
    290 static void InitializeHighMemEnd() {
    291 #if !ASAN_FIXED_MAPPING
    292   kHighMemEnd = GetMaxVirtualAddress();
    293   // Increase kHighMemEnd to make sure it's properly
    294   // aligned together with kHighMemBeg:
    295   kHighMemEnd |= SHADOW_GRANULARITY * GetPageSizeCached() - 1;
    296 #endif  // !ASAN_FIXED_MAPPING
    297   CHECK_EQ((kHighMemBeg % GetPageSizeCached()), 0);
    298 }
    299 
    300 static void ProtectGap(uptr addr, uptr size) {
    301   void *res = MmapNoAccess(addr, size);
    302   if (addr == (uptr)res)
    303     return;
    304   Report("ERROR: Failed to protect the shadow gap. "
    305          "ASan cannot proceed correctly. ABORTING.\n");
    306   DumpProcessMap();
    307   Die();
    308 }
    309 
    310 static void PrintAddressSpaceLayout() {
    311   Printf("|| `[%p, %p]` || HighMem    ||\n",
    312          (void*)kHighMemBeg, (void*)kHighMemEnd);
    313   Printf("|| `[%p, %p]` || HighShadow ||\n",
    314          (void*)kHighShadowBeg, (void*)kHighShadowEnd);
    315   if (kMidMemBeg) {
    316     Printf("|| `[%p, %p]` || ShadowGap3 ||\n",
    317            (void*)kShadowGap3Beg, (void*)kShadowGap3End);
    318     Printf("|| `[%p, %p]` || MidMem     ||\n",
    319            (void*)kMidMemBeg, (void*)kMidMemEnd);
    320     Printf("|| `[%p, %p]` || ShadowGap2 ||\n",
    321            (void*)kShadowGap2Beg, (void*)kShadowGap2End);
    322     Printf("|| `[%p, %p]` || MidShadow  ||\n",
    323            (void*)kMidShadowBeg, (void*)kMidShadowEnd);
    324   }
    325   Printf("|| `[%p, %p]` || ShadowGap  ||\n",
    326          (void*)kShadowGapBeg, (void*)kShadowGapEnd);
    327   if (kLowShadowBeg) {
    328     Printf("|| `[%p, %p]` || LowShadow  ||\n",
    329            (void*)kLowShadowBeg, (void*)kLowShadowEnd);
    330     Printf("|| `[%p, %p]` || LowMem     ||\n",
    331            (void*)kLowMemBeg, (void*)kLowMemEnd);
    332   }
    333   Printf("MemToShadow(shadow): %p %p %p %p",
    334          (void*)MEM_TO_SHADOW(kLowShadowBeg),
    335          (void*)MEM_TO_SHADOW(kLowShadowEnd),
    336          (void*)MEM_TO_SHADOW(kHighShadowBeg),
    337          (void*)MEM_TO_SHADOW(kHighShadowEnd));
    338   if (kMidMemBeg) {
    339     Printf(" %p %p",
    340            (void*)MEM_TO_SHADOW(kMidShadowBeg),
    341            (void*)MEM_TO_SHADOW(kMidShadowEnd));
    342   }
    343   Printf("\n");
    344   Printf("redzone=%zu\n", (uptr)flags()->redzone);
    345   Printf("max_redzone=%zu\n", (uptr)flags()->max_redzone);
    346   Printf("quarantine_size_mb=%zuM\n", (uptr)flags()->quarantine_size_mb);
    347   Printf("malloc_context_size=%zu\n",
    348          (uptr)common_flags()->malloc_context_size);
    349 
    350   Printf("SHADOW_SCALE: %zx\n", (uptr)SHADOW_SCALE);
    351   Printf("SHADOW_GRANULARITY: %zx\n", (uptr)SHADOW_GRANULARITY);
    352   Printf("SHADOW_OFFSET: %zx\n", (uptr)SHADOW_OFFSET);
    353   CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7);
    354   if (kMidMemBeg)
    355     CHECK(kMidShadowBeg > kLowShadowEnd &&
    356           kMidMemBeg > kMidShadowEnd &&
    357           kHighShadowBeg > kMidMemEnd);
    358 }
    359 
    360 static void AsanInitInternal() {
    361   if (LIKELY(asan_inited)) return;
    362   SanitizerToolName = "AddressSanitizer";
    363   CHECK(!asan_init_is_running && "ASan init calls itself!");
    364   asan_init_is_running = true;
    365 
    366   // Initialize flags. This must be done early, because most of the
    367   // initialization steps look at flags().
    368   InitializeFlags();
    369 
    370   SetCanPoisonMemory(flags()->poison_heap);
    371   SetMallocContextSize(common_flags()->malloc_context_size);
    372 
    373   InitializeHighMemEnd();
    374 
    375   // Make sure we are not statically linked.
    376   AsanDoesNotSupportStaticLinkage();
    377 
    378   // Install tool-specific callbacks in sanitizer_common.
    379   SetDieCallback(AsanDie);
    380   SetCheckFailedCallback(AsanCheckFailed);
    381   SetPrintfAndReportCallback(AppendToErrorMessageBuffer);
    382 
    383   __sanitizer_set_report_path(common_flags()->log_path);
    384 
    385   // Enable UAR detection, if required.
    386   __asan_option_detect_stack_use_after_return =
    387       flags()->detect_stack_use_after_return;
    388 
    389   // Re-exec ourselves if we need to set additional env or command line args.
    390   MaybeReexec();
    391 
    392   // Setup internal allocator callback.
    393   SetLowLevelAllocateCallback(OnLowLevelAllocate);
    394 
    395   InitializeAsanInterceptors();
    396 
    397   // Enable system log ("adb logcat") on Android.
    398   // Doing this before interceptors are initialized crashes in:
    399   // AsanInitInternal -> android_log_write -> __interceptor_strcmp
    400   AndroidLogInit();
    401 
    402   ReplaceSystemMalloc();
    403 
    404   uptr shadow_start = kLowShadowBeg;
    405   if (kLowShadowBeg)
    406     shadow_start -= GetMmapGranularity();
    407   bool full_shadow_is_available =
    408       MemoryRangeIsAvailable(shadow_start, kHighShadowEnd);
    409 
    410 #if SANITIZER_LINUX && defined(__x86_64__) && defined(_LP64) &&                \
    411     !ASAN_FIXED_MAPPING
    412   if (!full_shadow_is_available) {
    413     kMidMemBeg = kLowMemEnd < 0x3000000000ULL ? 0x3000000000ULL : 0;
    414     kMidMemEnd = kLowMemEnd < 0x3000000000ULL ? 0x4fffffffffULL : 0;
    415   }
    416 #endif
    417 
    418   if (Verbosity()) PrintAddressSpaceLayout();
    419 
    420   DisableCoreDumperIfNecessary();
    421 
    422   if (full_shadow_is_available) {
    423     // mmap the low shadow plus at least one page at the left.
    424     if (kLowShadowBeg)
    425       ReserveShadowMemoryRange(shadow_start, kLowShadowEnd);
    426     // mmap the high shadow.
    427     ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd);
    428     // protect the gap.
    429     ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
    430     CHECK_EQ(kShadowGapEnd, kHighShadowBeg - 1);
    431   } else if (kMidMemBeg &&
    432       MemoryRangeIsAvailable(shadow_start, kMidMemBeg - 1) &&
    433       MemoryRangeIsAvailable(kMidMemEnd + 1, kHighShadowEnd)) {
    434     CHECK(kLowShadowBeg != kLowShadowEnd);
    435     // mmap the low shadow plus at least one page at the left.
    436     ReserveShadowMemoryRange(shadow_start, kLowShadowEnd);
    437     // mmap the mid shadow.
    438     ReserveShadowMemoryRange(kMidShadowBeg, kMidShadowEnd);
    439     // mmap the high shadow.
    440     ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd);
    441     // protect the gaps.
    442     ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
    443     ProtectGap(kShadowGap2Beg, kShadowGap2End - kShadowGap2Beg + 1);
    444     ProtectGap(kShadowGap3Beg, kShadowGap3End - kShadowGap3Beg + 1);
    445   } else {
    446     Report("Shadow memory range interleaves with an existing memory mapping. "
    447            "ASan cannot proceed correctly. ABORTING.\n");
    448     Report("ASan shadow was supposed to be located in the [%p-%p] range.\n",
    449            shadow_start, kHighShadowEnd);
    450     DumpProcessMap();
    451     Die();
    452   }
    453 
    454   AsanTSDInit(PlatformTSDDtor);
    455   InstallDeadlySignalHandlers(AsanOnSIGSEGV);
    456 
    457   AllocatorOptions allocator_options;
    458   allocator_options.SetFrom(flags(), common_flags());
    459   InitializeAllocator(allocator_options);
    460 
    461   MaybeStartBackgroudThread();
    462   SetSoftRssLimitExceededCallback(AsanSoftRssLimitExceededCallback);
    463 
    464   // On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited
    465   // should be set to 1 prior to initializing the threads.
    466   asan_inited = 1;
    467   asan_init_is_running = false;
    468 
    469   if (flags()->atexit)
    470     Atexit(asan_atexit);
    471 
    472   InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
    473 
    474   // Now that ASan runtime is (mostly) initialized, deactivate it if
    475   // necessary, so that it can be re-activated when requested.
    476   if (flags()->start_deactivated)
    477     AsanDeactivate();
    478 
    479   // interceptors
    480   InitTlsSize();
    481 
    482   // Create main thread.
    483   AsanThread *main_thread = AsanThread::Create(
    484       /* start_routine */ nullptr, /* arg */ nullptr, /* parent_tid */ 0,
    485       /* stack */ nullptr, /* detached */ true);
    486   CHECK_EQ(0, main_thread->tid());
    487   SetCurrentThread(main_thread);
    488   main_thread->ThreadStart(internal_getpid(),
    489                            /* signal_thread_is_registered */ nullptr);
    490   force_interface_symbols();  // no-op.
    491   SanitizerInitializeUnwinder();
    492 
    493 #if CAN_SANITIZE_LEAKS
    494   __lsan::InitCommonLsan();
    495   if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) {
    496     Atexit(__lsan::DoLeakCheck);
    497   }
    498 #endif  // CAN_SANITIZE_LEAKS
    499 
    500 #if CAN_SANITIZE_UB
    501   __ubsan::InitAsPlugin();
    502 #endif
    503 
    504   InitializeSuppressions();
    505 
    506   VReport(1, "AddressSanitizer Init done\n");
    507 }
    508 
    509 // Initialize as requested from some part of ASan runtime library (interceptors,
    510 // allocator, etc).
    511 void AsanInitFromRtl() {
    512   AsanInitInternal();
    513 }
    514 
    515 #if ASAN_DYNAMIC
    516 // Initialize runtime in case it's LD_PRELOAD-ed into unsanitized executable
    517 // (and thus normal initializer from .preinit_array haven't run).
    518 
    519 class AsanInitializer {
    520 public:  // NOLINT
    521   AsanInitializer() {
    522     AsanCheckIncompatibleRT();
    523     AsanCheckDynamicRTPrereqs();
    524     AsanInitFromRtl();
    525   }
    526 };
    527 
    528 static AsanInitializer asan_initializer;
    529 #endif  // ASAN_DYNAMIC
    530 
    531 }  // namespace __asan
    532 
    533 // ---------------------- Interface ---------------- {{{1
    534 using namespace __asan;  // NOLINT
    535 
    536 int NOINLINE __asan_set_error_exit_code(int exit_code) {
    537   int old = flags()->exitcode;
    538   flags()->exitcode = exit_code;
    539   return old;
    540 }
    541 
    542 void NOINLINE __asan_handle_no_return() {
    543   int local_stack;
    544   AsanThread *curr_thread = GetCurrentThread();
    545   CHECK(curr_thread);
    546   uptr PageSize = GetPageSizeCached();
    547   uptr top = curr_thread->stack_top();
    548   uptr bottom = ((uptr)&local_stack - PageSize) & ~(PageSize-1);
    549   static const uptr kMaxExpectedCleanupSize = 64 << 20;  // 64M
    550   if (top - bottom > kMaxExpectedCleanupSize) {
    551     static bool reported_warning = false;
    552     if (reported_warning)
    553       return;
    554     reported_warning = true;
    555     Report("WARNING: ASan is ignoring requested __asan_handle_no_return: "
    556            "stack top: %p; bottom %p; size: %p (%zd)\n"
    557            "False positive error reports may follow\n"
    558            "For details see "
    559            "http://code.google.com/p/address-sanitizer/issues/detail?id=189\n",
    560            top, bottom, top - bottom, top - bottom);
    561     return;
    562   }
    563   PoisonShadow(bottom, top - bottom, 0);
    564   if (curr_thread->has_fake_stack())
    565     curr_thread->fake_stack()->HandleNoReturn();
    566 }
    567 
    568 void NOINLINE __asan_set_death_callback(void (*callback)(void)) {
    569   SetUserDieCallback(callback);
    570 }
    571 
    572 // Initialize as requested from instrumented application code.
    573 // We use this call as a trigger to wake up ASan from deactivated state.
    574 void __asan_init() {
    575   AsanCheckIncompatibleRT();
    576   AsanActivate();
    577   AsanInitInternal();
    578 }
    579