[PATCH] D53528: [sanitizer] Avoid calling a nullptr in MonotonicNanoTime if interceptors are not yet initialized
Kuba (Brecka) Mracek via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 22 13:50:11 PDT 2018
kubamracek created this revision.
kubamracek added reviewers: cryptoad, alekseyshl, krytarowski.
kubamracek added a project: Sanitizers.
Herald added a subscriber: Sanitizers.
I'm seeing 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. Attaching the backtrace of how that happens below. 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.
* thread #1, name = 'hello', stop reason = signal SIGSEGV: invalid address
* frame #0: 0x0000000000000000
frame #1: 0x00005555555dbf0a ::real_clock_gettime
frame #2: 0x00005555555b14f0 __sanitizer::MonotonicNanoTime
frame #3: 0x000055555562d430 __sanitizer::SizeClassAllocator64<...>::PopulateFreeArray
frame #4: 0x000055555562d161 __sanitizer::SizeClassAllocator64<...>::GetFromAllocator
frame #5: 0x000055555562cf5d __sanitizer::SizeClassAllocator64LocalCache<...>::Refill
frame #6: 0x000055555562c845 __sanitizer::SizeClassAllocator64LocalCache<...>::Allocate
frame #7: 0x0000555555629e75 __sanitizer::CombinedAllocator<...>::Allocate
frame #8: 0x0000555555628c02 __tsan::user_alloc_internal
frame #9: 0x0000555555629168 __tsan::user_calloc
frame #10: 0x00005555555c7a78 ::__interceptor_calloc
frame #11: 0x00007ffff6ded7e5 libdl.so.2`___lldb_unnamed_symbol11$$libdl.so.2 + 277
frame #12: 0x00007ffff6ded166 libdl.so.2`dlsym + 118
frame #13: 0x00005555556317b8 __interception::GetRealFunctionAddress
frame #14: 0x0000555555601c7c InitializeCommonInterceptors
frame #15: 0x0000555555600b6a __tsan::InitializeInterceptors
frame #16: 0x000055555555cc71 __tsan::Initialize
frame #17: 0x00005555555c6340 __tsan::ScopedInterceptor::ScopedInterceptor
frame #18: 0x00005555555c6f18 ::__interceptor___cxa_atexit
frame #19: 0x00007ffff6af22e6 libstdc++.so.6`___lldb_unnamed_symbol241$$libstdc++.so.6 + 70
frame #20: 0x00007ffff7de5733 ld-linux-x86-64.so.2`___lldb_unnamed_symbol50$$ld-linux-x86-64.so.2 + 259
frame #21: 0x00007ffff7dd60ca ld-linux-x86-64.so.2`___lldb_unnamed_symbol4$$ld-linux-x86-64.so.2 + 105
Repository:
rCRT Compiler Runtime
https://reviews.llvm.org/D53528
Files:
lib/sanitizer_common/sanitizer_linux_libcdep.cc
Index: lib/sanitizer_common/sanitizer_linux_libcdep.cc
===================================================================
--- lib/sanitizer_common/sanitizer_linux_libcdep.cc
+++ lib/sanitizer_common/sanitizer_linux_libcdep.cc
@@ -770,11 +770,14 @@
// vDSO function pointers haven't been initialized yet. __progname is
// initialized after the vDSO function pointers, so if it exists, is not null
// and is not empty, we can use clock_gettime.
+namespace __interception { int (*real_clock_gettime)(u32 clk_id, void *tp); }
extern "C" SANITIZER_WEAK_ATTRIBUTE char *__progname;
INLINE bool CanUseVDSO() {
// Bionic is safe, it checks for the vDSO function pointers to be initialized.
if (SANITIZER_ANDROID)
return true;
+ if (!__interception::real_clock_gettime)
+ return false;
if (&__progname && __progname && *__progname)
return true;
return false;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D53528.170488.patch
Type: text/x-patch
Size: 882 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181022/f178215a/attachment.bin>
More information about the llvm-commits
mailing list