The sysctlnametomib function is called from tsan::Initialize via
sanitizer::internal_sysctlbyname (see stack trace below). This results
in a fatal error since sysctlnametomib has not been intercepted yet.
This patch allows internal_sysctlbyname to be called before
__tsan::Initialize() has completed. On FreeBSD >= 1300045 sysctlbyname()
is a real syscall, but for older versions it calls sysctlnametomib()
followed by sysctl(). To avoid calling the intercepted version, look up
the real sysctlnametomib() followed by internal_sysctl() if the
syscall is not available.
This reduces check-sanitizer failures from 62 to 11 for me.
34433==FATAL: ThreadSanitizer: failed to intercept sysctlnametomib
#0 __sanitizer::Die ()
at /exports/users/alr48/sources/upstream-llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_termination.cpp:51
#1 0x00000000002a2de6 in __interceptor_sysctlnametomib (sname=0x2146cb "kern.elf64.aslr.pie_enable",
name=0x7fffffffce10, namelenp=0x7fffffffce08) at /exports/users/alr48/sources/upstream-llvm-project/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:7908
#2 0x000000080061ea0d in sysctlbyname () from /lib/libc.so.7
#3 0x00000000002515a0 in __sanitizer::internal_sysctlbyname (sname=0x2146cb "kern.elf64.aslr.pie_enable",
oldp=0x7fffffffcf2c, oldlenp=0x7fffffffcf20, newp=0x0, newlen=0) at /exports/users/alr48/sources/upstream-llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp:803
#4 0x0000000000252823 in __sanitizer::CheckASLR ()
at /exports/users/alr48/sources/upstream-llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp:2152
#5 0x00000000002dd2ea in __tsan::Initialize (thr=0x800901980)
at /exports/users/alr48/sources/upstream-llvm-project/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp:367
#6 0x000000000027cdd0 in __tsan::ScopedInterceptor::ScopedInterceptor (this=0x7fffffffd030, thr=0x800901980,
fname=0x21c731 "readlink", pc=34366042556) at /exports/users/alr48/sources/upstream-llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp:255
#7 0x00000000002a0055 in __interceptor_readlink (path=0x80051d509 "/etc/malloc.conf", buf=0x7fffffffd0b0 "",
bufsiz=1024) at /exports/users/alr48/sources/upstream-llvm-project/compiler-rt/lib/tsan/../sanitizer_common/sanitizer_common_interceptors.inc:7151
#8 0x00000008006031bc in ?? () from /lib/libc.so.7
#9 0x0000000800602b08 in ?? () from /lib/libc.so.7
#10 0x000000080032646e in ?? () from /libexec/ld-elf.so.1
#11 0x0000000000000000 in ?? ()
Why not like this?