diff options
author | Francis Ricci <francisjricci@gmail.com> | 2017-07-18 20:18:32 +0000 |
---|---|---|
committer | Francis Ricci <francisjricci@gmail.com> | 2017-07-18 20:18:32 +0000 |
commit | f9d9566dc29f527537dffe68cf2a2deb1d12b177 (patch) | |
tree | 0e09f7c03198fbec0d90e4c7dd771a2c84c11eb4 /lib/asan/asan_interceptors.cc | |
parent | 13c2d08571baab9982f01acb1d302049bdace581 (diff) |
Don't call exit() from atexit handlers on Darwin
Summary:
Calling exit() from an atexit handler is undefined behavior.
On Linux, it's unavoidable, since we cannot intercept exit (_exit isn't called
if a user program uses return instead of exit()), and I haven't
seen it cause issues regardless.
However, on Darwin, I have a fairly complex internal test that hangs roughly
once in every 300 runs after leak reporting finishes, which is resolved with
this patch, and is presumably due to the undefined behavior (since the Die() is
the only thing that happens after the end of leak reporting).
In addition, this is the way TSan works as well, where an atexit handler+Die()
is used on Linux, and an _exit() interceptor is used on Darwin. I'm not sure if it's
intentionally structured that way in TSan, since TSan sets up the atexit handler and the
_exit() interceptor on both platforms, but I have observed that on Darwin, only the
_exit() interceptor is used, and on Linux the atexit handler is used.
There is some additional related discussion here: https://reviews.llvm.org/D35085
Reviewers: alekseyshl, kubamracek
Subscribers: eugenis, vsk, llvm-commits
Differential Revision: https://reviews.llvm.org/D35513
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@308353 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/asan/asan_interceptors.cc')
-rw-r--r-- | lib/asan/asan_interceptors.cc | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/lib/asan/asan_interceptors.cc b/lib/asan/asan_interceptors.cc index ed12a9ac9..34ca22b86 100644 --- a/lib/asan/asan_interceptors.cc +++ b/lib/asan/asan_interceptors.cc @@ -178,6 +178,10 @@ void SetThreadName(const char *name) { } int OnExit() { + if (CAN_SANITIZE_LEAKS && common_flags()->detect_leaks && + __lsan::HasReportedLeaks()) { + return common_flags()->exitcode; + } // FIXME: ask frontend whether we need to return failure. return 0; } |