diff options
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc | 8 | ||||
-rw-r--r-- | compiler-rt/test/asan/TestCases/Linux/stack-trace-dlclose.cc | 40 |
2 files changed, 48 insertions, 0 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc index d7d5e9e4a2c..c68149daa81 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc @@ -37,6 +37,14 @@ void StackTrace::PrintStack(const uptr *addr, uptr size) { uptr pc = GetPreviousInstructionPc(addr[i]); uptr addr_frames_num = Symbolizer::GetOrInit()->SymbolizePC( pc, addr_frames.data(), addr_frames.size()); + if (addr_frames_num == 0) { + frame_desc.clear(); + PrintStackFramePrefix(&frame_desc, frame_num, pc); + frame_desc.append(" (<unknown module>)"); + Printf("%s\n", frame_desc.data()); + frame_num++; + continue; + } for (uptr j = 0; j < addr_frames_num; j++) { AddressInfo &info = addr_frames[j]; frame_desc.clear(); diff --git a/compiler-rt/test/asan/TestCases/Linux/stack-trace-dlclose.cc b/compiler-rt/test/asan/TestCases/Linux/stack-trace-dlclose.cc new file mode 100644 index 00000000000..3c6812b02fc --- /dev/null +++ b/compiler-rt/test/asan/TestCases/Linux/stack-trace-dlclose.cc @@ -0,0 +1,40 @@ +// RUN: %clangxx_asan -DSHARED %s -shared -o %T/stack_trace_dlclose.so -fPIC +// RUN: %clangxx_asan -DSO_DIR=\"%T\" %s -o %t +// RUN: ASAN_OPTIONS=exitcode=0 %run %t 2>&1 | FileCheck %s + +#include <assert.h> +#include <dlfcn.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> + +#include <sanitizer/common_interface_defs.h> + +#ifdef SHARED +extern "C" { +void *foo() { + return malloc(1); +} +} +#else +void *handle; + +int main(int argc, char **argv) { + void *handle = dlopen(SO_DIR "/stack_trace_dlclose.so", RTLD_LAZY); + assert(handle); + void *(*foo)() = (void *(*)())dlsym(handle, "foo"); + assert(foo); + void *p = foo(); + assert(p); + dlclose(handle); + + free(p); + free(p); // double-free + + return 0; +} +#endif + +// CHECK: {{ #0 0x.* in malloc}} +// CHECK: {{ #1 0x.* \(<unknown module>\)}} +// CHECK: {{ #2 0x.* in main}} |