diff --git a/compiler-rt/lib/asan/asan_fuchsia.cpp b/compiler-rt/lib/asan/asan_fuchsia.cpp --- a/compiler-rt/lib/asan/asan_fuchsia.cpp +++ b/compiler-rt/lib/asan/asan_fuchsia.cpp @@ -14,16 +14,17 @@ #include "sanitizer_common/sanitizer_fuchsia.h" #if SANITIZER_FUCHSIA -#include "asan_interceptors.h" -#include "asan_internal.h" -#include "asan_stack.h" -#include "asan_thread.h" - #include #include #include #include +#include "asan_interceptors.h" +#include "asan_internal.h" +#include "asan_stack.h" +#include "asan_thread.h" +#include "lsan/lsan_common.h" + namespace __asan { // The system already set up the shadow memory for us. @@ -31,7 +32,8 @@ // AsanInitInternal->InitializeHighMemEnd (asan_rtl.cpp). // Just do some additional sanity checks here. void InitializeShadowMemory() { - if (Verbosity()) PrintAddressSpaceLayout(); + if (Verbosity()) + PrintAddressSpaceLayout(); // Make sure SHADOW_OFFSET doesn't use __asan_shadow_memory_dynamic_address. __asan_shadow_memory_dynamic_address = kDefaultShadowSentinel; @@ -148,7 +150,8 @@ uptr stack_size) { EnsureMainThreadIDIsCorrect(); // Strict init-order checking is thread-hostile. - if (flags()->strict_init_order) StopInitOrderChecking(); + if (flags()->strict_init_order) + StopInitOrderChecking(); GET_STACK_TRACE_THREAD; u32 parent_tid = GetCurrentTidOrInvalid(); @@ -227,4 +230,10 @@ __asan::ThreadExitHook(hook, reinterpret_cast(self)); } +// This is declared (in extern "C") by . +// _Exit calls this directly to intercept and change the status value. +int __sanitizer_process_exit_hook(int status) { + return __lsan::ExitHook(status, __asan::flags()->halt_on_error); +} + #endif // SANITIZER_FUCHSIA diff --git a/compiler-rt/lib/asan/asan_rtl.cpp b/compiler-rt/lib/asan/asan_rtl.cpp --- a/compiler-rt/lib/asan/asan_rtl.cpp +++ b/compiler-rt/lib/asan/asan_rtl.cpp @@ -500,12 +500,15 @@ if (CAN_SANITIZE_LEAKS) { __lsan::InitCommonLsan(); + // On Fuchsia, leak detection is done by a special hook after atexit hooks. +#if !SANITIZER_FUCHSIA if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) { if (flags()->halt_on_error) Atexit(__lsan::DoLeakCheck); else Atexit(__lsan::DoRecoverableLeakCheckVoid); } +#endif } #if CAN_SANITIZE_UB diff --git a/compiler-rt/lib/lsan/lsan.cpp b/compiler-rt/lib/lsan/lsan.cpp --- a/compiler-rt/lib/lsan/lsan.cpp +++ b/compiler-rt/lib/lsan/lsan.cpp @@ -104,8 +104,11 @@ InstallDeadlySignalHandlers(LsanOnDeadlySignal); InitializeMainThread(); + // On Fuchsia, leak detection is done by a special hook after atexit hooks. +#if !SANITIZER_FUCHSIA if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) Atexit(DoLeakCheck); +#endif InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir); diff --git a/compiler-rt/lib/lsan/lsan_common.h b/compiler-rt/lib/lsan/lsan_common.h --- a/compiler-rt/lib/lsan/lsan_common.h +++ b/compiler-rt/lib/lsan/lsan_common.h @@ -250,6 +250,11 @@ // Run platform-specific leak handlers. void HandleLeaks(); +#if SANITIZER_FUCHSIA +// __sanitizer_process_exit_hook calls this. +int ExitHook(int status, bool halt_on_error); +#endif + // Wrapper for chunk metadata operations. class LsanMetadata { public: diff --git a/compiler-rt/lib/lsan/lsan_common_fuchsia.cpp b/compiler-rt/lib/lsan/lsan_common_fuchsia.cpp --- a/compiler-rt/lib/lsan/lsan_common_fuchsia.cpp +++ b/compiler-rt/lib/lsan/lsan_common_fuchsia.cpp @@ -51,7 +51,13 @@ // behavior and causes rare race conditions. void HandleLeaks() {} -int ExitHook(int status) { +int ExitHook(int status, bool halt_on_error) { + if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) { + if (halt_on_error) + DoLeakCheck(); + else + DoRecoverableLeakCheckVoid(); + } return status == 0 && HasReportedLeaks() ? common_flags()->exitcode : status; } @@ -157,10 +163,4 @@ } // namespace __lsan -// This is declared (in extern "C") by . -// _Exit calls this directly to intercept and change the status value. -int __sanitizer_process_exit_hook(int status) { - return __lsan::ExitHook(status); -} - #endif diff --git a/compiler-rt/lib/lsan/lsan_fuchsia.cpp b/compiler-rt/lib/lsan/lsan_fuchsia.cpp --- a/compiler-rt/lib/lsan/lsan_fuchsia.cpp +++ b/compiler-rt/lib/lsan/lsan_fuchsia.cpp @@ -120,4 +120,10 @@ // All per-thread destructors have already been called. void __sanitizer_thread_exit_hook(void *hook, thrd_t self) { ThreadFinish(); } +// This is declared (in extern "C") by . +// _Exit calls this directly to intercept and change the status value. +int __sanitizer_process_exit_hook(int status) { + return __lsan::ExitHook(status, true); +} + #endif // SANITIZER_FUCHSIA