diff options
author | Kuba Mracek <mracek@apple.com> | 2018-10-24 18:40:08 +0000 |
---|---|---|
committer | Kuba Mracek <mracek@apple.com> | 2018-10-24 18:40:08 +0000 |
commit | d48e4d78293ca3a91b28c8abd77464a709263d06 (patch) | |
tree | 8f21a37f38d05cef423f647bea74e27422899cb1 | |
parent | 195d80eda7da40d35e8cac68d2e1294a446a33f7 (diff) |
[sanitizer] Avoid calling a nullptr in MonotonicNanoTime if interceptors are not yet initialized
There's a TSan startup crash on Linux when used in Swift programs, where MonotonicNanoTime will try to call real_clock_gettime and then jump to NULL because interceptors are not yet initialized. This is on Ubuntu 18.04. Looks like TSan's main Initialize() function is called at a point where __progname is already set, but interceptors aren't yet set up. Let's fix this by checking whether interceptors are initialized in MonotonicNanoTime.
Differential Revision: https://reviews.llvm.org/D53528
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@345174 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/sanitizer_common/sanitizer_linux_libcdep.cc | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/lib/sanitizer_common/sanitizer_linux_libcdep.cc b/lib/sanitizer_common/sanitizer_linux_libcdep.cc index 7859557c8..93b68ed4b 100644 --- a/lib/sanitizer_common/sanitizer_linux_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_linux_libcdep.cc @@ -782,12 +782,15 @@ INLINE bool CanUseVDSO() { // MonotonicNanoTime is a timing function that can leverage the vDSO by calling // clock_gettime. real_clock_gettime only exists if clock_gettime is -// intercepted, so define it weakly and use it if available. +// intercepted, so define it weakly and use it if available. MonotonicNanoTime +// might also be called when interceptors are not yet initialized, so check for +// that as well. extern "C" SANITIZER_WEAK_ATTRIBUTE int real_clock_gettime(u32 clk_id, void *tp); +namespace __interception { int (*real_clock_gettime)(u32 clk_id, void *tp); } u64 MonotonicNanoTime() { timespec ts; - if (CanUseVDSO()) { + if (CanUseVDSO() && __interception::real_clock_gettime) { if (&real_clock_gettime) real_clock_gettime(CLOCK_MONOTONIC, &ts); else |