ARM thumb/thumb2 frame pointer is inconsistent on GCC and Clang [1]
and fast-unwider is also unreliable when mixing arm and thumb code [2].
The fast unwinder on ARM tries to probe and compare the frame-pointer
at different stack layout positions and it works reliable only on
systems where all the libraries were built in arm mode (either with
gcc or clang) or with clang in thmb mode (which uses the same stack
frame pointer layout in arm and thumb).
However when mixing objects built with different abi modes the
fast unwinder is still problematic as shown by the failures on the
AddressSanitizer.ThreadStackReuseTest. For these failures, the
malloc is called by the loader itself and since it has been built
with a thum enabled gcc, the stack frame is not correctly obtained
and the suppression rule is not applied (resulting in a leak warning).
The check for fast-unwinder-works is also changed: instead of checking
f it is explicit enabled in the compiler flags, it now checks if
compiler defined thumb pre-processor.
This should fix BZ#44158.
[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92172
[2] https://bugs.llvm.org/show_bug.cgi?id=44158
Reviewed By: eugenis
Differential Revision: https://reviews.llvm.org/D88958
Adds a check to avoid symbolization when printing stack traces if the
stack_trace_format flag does not need it. While there is a symbolize
flag that can be turned off to skip some of the symbolization,
SymbolizePC() still unconditionally looks up the module name and offset.
Avoid invoking SymbolizePC() at all if not needed.
This is an efficiency improvement when dumping all stack traces as part
of the memory profiler in D87120, for large stripped apps where we want
to symbolize as a post pass.
Differential Revision: https://reviews.llvm.org/D88361
After D88686, munmap uses MADV_DONTNEED to ensure zero-out before the
next access. Because the entire shadow space is created by MAP_PRIVATE
and MAP_ANONYMOUS, the first access is also on zero-filled values.
So it is fine to not zero-out data, but use madvise(MADV_DONTNEED) at
mmap. This reduces runtime
overhead.
Reviewed-by: morehouse
Differential Revision: https://reviews.llvm.org/D88755
TSan relies on C++ headers, so when libc++ is being built as part of
the runtimes build, include an explicit dependency on cxx-headers which
is the same approach that's already used for other sanitizers.
Differential Revision: https://reviews.llvm.org/D88912
[11/11] patch series to port ASAN for riscv64
These changes allow using ASAN on RISCV64 architecture.
The majority of existing tests are passing. With few exceptions (see below).
Tests we run on qemu and on "HiFive Unleashed" board.
Tests run:
```
Asan-riscv64-inline-Test - pass
Asan-riscv64-inline-Noinst-Test - pass
Asan-riscv64-calls-Noinst-Test - pass
Asan-riscv64-calls-Test - pass
```
Lit tests:
```
RISCV64LinuxConfig (282 supported, few failures)
RISCV64LinuxDynamicConfig (289 supported, few failures)
```
Lit failures:
```
TestCases/malloc_context_size.cpp - asan works, but backtrace misses some calls
TestCases/Linux/malloc_delete_mismatch.cpp - asan works, but backtrace misses some calls
TestCases/Linux/static_tls.cpp - "Can't guess glibc version" (under debugging)
TestCases/asan_and_llvm_coverage_test.cpp - missing libclang_rt.profile-riscv64.a
```
These failures are under debugging currently and shall be addressed in a
subsequent commits.
Depends On D87581
Reviewed By: eugenis, vitalybuka
Differential Revision: https://reviews.llvm.org/D87582
This moves the platform-specific parameter logic from asan into
lsan_common.h to lsan can share it.
Reviewed By: vitalybuka
Differential Revision: https://reviews.llvm.org/D87795
When an application does a lot of pairs of mmap and munmap, if we did
not release shadoe memory used by mmap addresses, this would increase
memory usage.
Reviewed-by: morehouse
Differential Revision: https://reviews.llvm.org/D88686
[7/11] patch series to port ASAN for riscv64
Depends On D87575
Reviewed By: eugenis, vitalybuka, luismarques
Differential Revision: https://reviews.llvm.org/D87577
Move some of the flags previously in Options, as well as the
UseMemoryTagging flag previously in the primary allocator, into an
atomic variable so that it can be updated while other threads are
running. Relaxed accesses are used because we only have the requirement
that the other threads see the new value eventually.
The code is set up so that the variable is generally loaded once per
allocation function call with the exception of some rarely used code
such as error handlers. The flag bits can generally stay in a register
during the execution of the allocation function which means that they
can be branched on with minimal overhead (e.g. TBZ on aarch64).
Differential Revision: https://reviews.llvm.org/D88523
`TestCases/log-path_test.cpp` currently `FAIL`s on Solaris:
$ env ASAN_OPTIONS=log_path=`for((i=0;i<10000;i++)); do echo -n $i; done` ./log-path_test.cpp.tmp
==5031==ERROR: Path is too long: 01234567...
Segmentation Fault (core dumped)
The `SEGV` happens here:
Thread 2 received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1 (LWP 1)]
0x00000000 in ?? ()
(gdb) where
#0 0x00000000 in ?? ()
#1 0x080a1e63 in __interceptor__exit (status=1)
at /vol/gcc/src/llvm/llvm/local/projects/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:3808
#2 0x08135ea8 in __sanitizer::internal__exit (exitcode=1)
at /vol/gcc/src/llvm/llvm/local/projects/compiler-rt/lib/sanitizer_common/sanitizer_solaris.cc:139
when `__interceptor__exit` tries to call `__interception::real__exit` which
is `NULL` at this point because the interceptors haven't been initialized yet.
Ultimately, the problem lies elsewhere, however: `internal__exit` in
`sanitizer_solaris.cpp` calls `_exit` itself since there doesn't exit a
non-intercepted version in `libc`. Using the `syscall` interface instead
isn't usually an option on Solaris because that interface isn't stable.
However, in the case of `SYS_exit` it can be used nonetheless: `SYS_exit`
has remained unchanged since at least Solaris 2.5.1 in 1996, and this is
what this patch does.
Tested on `amd64-pc-solaris2.11`.
Differential Revision: https://reviews.llvm.org/D88404
Said test was flaking on Fuchsia for non-obvious reasons, and only
for ASan variants (the release was returning 0).
It turned out that the templating was off, `true` being promoted to
a `s32` and used as the minimum interval argument. This meant that in
some circumstances, the normal release would occur, and the forced
release would have nothing to release, hence the 0 byte released.
The symbols are giving it away (note the 1):
```
scudo::SizeClassAllocator64<scudo::FixedSizeClassMap<scudo::DefaultSizeClassConfig>,24ul,1,2147483647,false>::releaseToOS(void)
```
This also probably means that there was no MTE version of that test!
Differential Revision: https://reviews.llvm.org/D88457
`atomic_compare_exchange_weak` is unused in Scudo, and its associated
test is actually wrong since the weak variant is allowed to fail
spuriously (thanks Roland).
This lead to flakes such as:
```
[ RUN ] ScudoAtomicTest.AtomicCompareExchangeTest
../../zircon/third_party/scudo/src/tests/atomic_test.cpp:98: Failure: Expected atomic_compare_exchange_weak(reinterpret_cast<T *>(&V), &OldVal, NewVal, memory_order_relaxed) is true.
Expected: true
Which is: 01
Actual : atomic_compare_exchange_weak(reinterpret_cast<T *>(&V), &OldVal, NewVal, memory_order_relaxed)
Which is: 00
../../zircon/third_party/scudo/src/tests/atomic_test.cpp💯 Failure: Expected atomic_compare_exchange_weak( reinterpret_cast<T *>(&V), &OldVal, NewVal, memory_order_relaxed) is false.
Expected: false
Which is: 00
Actual : atomic_compare_exchange_weak( reinterpret_cast<T *>(&V), &OldVal, NewVal, memory_order_relaxed)
Which is: 01
../../zircon/third_party/scudo/src/tests/atomic_test.cpp:101: Failure: Expected OldVal == NewVal.
Expected: NewVal
Which is: 24
Actual : OldVal
Which is: 42
[ FAILED ] ScudoAtomicTest.AtomicCompareExchangeTest (0 ms)
[----------] 2 tests from ScudoAtomicTest (1 ms total)
```
So I am removing this, if someone ever needs the weak variant, feel
free to add it back with a test that is not as terrible. This test was
initially ported from sanitizer_common, but their weak version calls
the strong version, so it works for them.
Differential Revision: https://reviews.llvm.org/D88443
Move smaller and frequently-accessed fields near the beginning
of the data structure in order to improve locality and reduce
the number of instructions required to form an access to those
fields. With this change I measured a ~5% performance improvement on
BM_malloc_sql_trace_default on aarch64 Android devices (Pixel 4 and
DragonBoard 845c).
Differential Revision: https://reviews.llvm.org/D88350
This commit adds an interceptor for the pthread_detach function,
calling into ThreadRegistry::DetachThread, allowing for thread contexts
to be reused.
Without this change, programs may fail when they create more than 8K
threads.
Fixes: https://bugs.llvm.org/show_bug.cgi?id=47389
Reviewed By: vitalybuka
Differential Revision: https://reviews.llvm.org/D88184
Add support for expanding the %t filename specifier in LLVM_PROFILE_FILE
to the TMPDIR environment variable. This is supported on all platforms.
On Darwin, TMPDIR is used to specify a temporary application-specific
scratch directory. When testing apps on remote devices, it can be
challenging for the host device to determine the correct TMPDIR, so it's
helpful to have the runtime do this work.
rdar://68524185
Differential Revision: https://reviews.llvm.org/D87332
`TestCases/malloc-no-intercept.c` `FAIL`s on Solaris/x86, e.g. with
`-Dtestfunc=mallinfo`:
/usr/bin/ld: /tmp/malloc-no-intercept-586529.o: in function `main':
/vol/llvm/src/llvm-project/dist/compiler-rt/test/asan/TestCases/malloc-no-intercept.c:30: undefined reference to `nonexistent_function'
clang-12: error: linker command failed with exit code 1 (use -v to see invocation)
This is not surprising, actually:
- `mallinfo` and `mallopt` only exist in `libmalloc`
- `pvalloc` doesn't exist all all
- `cfree` does exist in `libc`, but isn't declared in any public header and
the OpenSolaris sources reveal that it has a different signature than on
Linux
- only `memalign` is a public interface
To avoid this, this patch disables the interceptors for all but `meminfo`.
Additionally, the test is marked `UNSUPPORTED` on Solaris since the
`memalign` and `cfree` variants **do** link on Solaris.
Tested on `amd64-pc-solaris2.11`.
Differential Revision: https://reviews.llvm.org/D87898
This reverts commit 0caad9fe44.
This reverts commit c96d0cceb6.
Causes linker errors which were not fixed by the subsequent commit
either:
/home/nikic/llvm-project/compiler-rt/lib/asan/asan_rtl.cpp:503: error: undefined reference to '__asan::InstallAtExitCheckLeaks()'
Fix a potential UB in `appendSignedDecimal` (with -INT64_MIN) by making
it a special case.
Fix the terrible test cases for `isOwned`: I was pretty sloppy on those
and used some stack & static variables, but since `isOwned` accesses
memory prior to the pointer to check for the validity of the Scudo
header, it ended up being detected as some global and stack buffer out
of bounds accesses. So not I am using buffers with enough room so that
the test will not access memory prior to the variables.
With those fixes, the tests pass on the ASan+UBSan Fuchsia build.
Thanks to Roland for pointing those out!
Differential Revision: https://reviews.llvm.org/D88170
The `if (0)` isn't necessarily optimized out so as not to create
a link-time reference to LSan runtime functions that might not
exist. So use explicit conditional compilation instead.
Reviewed By: phosek
Differential Revision: https://reviews.llvm.org/D88173
Fuchsia's system libraries are instrumented and use the lsan
allocator for internal purposes. So leak checking needs to run
after all atexit hooks and after the system libraries' internal
exit-time hooks. The <zircon/sanitizer.h> hook API calls the
__sanitizer_process_exit_hook function at exactly the right time.
Reviewed By: vitalybuka, phosek
Differential Revision: https://reviews.llvm.org/D86171
implements glibc-like wrappers over Linux syscalls.
[3/11] patch series to port ASAN for riscv64
Depends On D87998
Reviewed By: eugenis
Differential Revision: https://reviews.llvm.org/D87572
This patch enables support for building compiler-rt builtins for 32-bit
Power arch on AIX. For now, we leave out the specialized ppc builtin
implementations for 128-bit long double and friends since those will
need some special handling for AIX.
Reviewed By: hubert.reinterpretcast
Differential Revision: https://reviews.llvm.org/D87383
https://reviews.llvm.org/D87420 removed the uses of the pthread key,
but the key itself was left in the shared TSD registry. It is created
on registry initialization, and destroyed on registry teardown.
There is really no use for it now, so we can just remove it.
Differential Revision: https://reviews.llvm.org/D88046
since we will be building both 32-bit and 64-bit compiler-rt builtins
from a single configuration.
Reviewed By: hubert.reinterpretcast
Differential Revision: https://reviews.llvm.org/D87113