diff options
| author | Kuba Brecka <kuba.brecka@gmail.com> | 2014-07-15 17:33:23 +0000 |
|---|---|---|
| committer | Kuba Brecka <kuba.brecka@gmail.com> | 2014-07-15 17:33:23 +0000 |
| commit | 58f44dce9609be8680710e85162820574056a4ad (patch) | |
| tree | eef3a95cf629231a1c30e7a087885800b77c4820 /compiler-rt/lib/asan/asan_debugging.cc | |
| parent | 8587711164cf478d438074b22ef887a2717a5096 (diff) | |
| download | bcm5719-llvm-58f44dce9609be8680710e85162820574056a4ad.tar.gz bcm5719-llvm-58f44dce9609be8680710e85162820574056a4ad.zip | |
[ASan] Add ASan debugging API to get malloc/free stack traces and shadow memory mapping info
Reviewed at http://reviews.llvm.org/D4466
llvm-svn: 213080
Diffstat (limited to 'compiler-rt/lib/asan/asan_debugging.cc')
| -rw-r--r-- | compiler-rt/lib/asan/asan_debugging.cc | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/compiler-rt/lib/asan/asan_debugging.cc b/compiler-rt/lib/asan/asan_debugging.cc new file mode 100644 index 00000000000..05198a78703 --- /dev/null +++ b/compiler-rt/lib/asan/asan_debugging.cc @@ -0,0 +1,74 @@ +//===-- asan_debugging.cc -------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// This file contains various functions that are generally useful to call when +// using a debugger (LLDB, GDB). +//===----------------------------------------------------------------------===// + +#include "asan_allocator.h" +#include "asan_flags.h" +#include "asan_internal.h" +#include "asan_mapping.h" +#include "asan_thread.h" + +namespace __asan { + +uptr AsanGetStack(uptr addr, uptr *trace, uptr size, u32 *thread_id, + bool alloc_stack) { + AsanChunkView chunk = FindHeapChunkByAddress(addr); + if (!chunk.IsValid()) return 0; + + StackTrace stack; + if (alloc_stack) { + if (chunk.AllocTid() == kInvalidTid) return 0; + chunk.GetAllocStack(&stack); + if (thread_id) *thread_id = chunk.AllocTid(); + } else { + if (chunk.FreeTid() == kInvalidTid) return 0; + chunk.GetFreeStack(&stack); + if (thread_id) *thread_id = chunk.FreeTid(); + } + + if (trace && size) { + if (size > kStackTraceMax) + size = kStackTraceMax; + if (size > stack.size) + size = stack.size; + for (uptr i = 0; i < size; i++) + trace[i] = StackTrace::GetPreviousInstructionPc(stack.trace[i]); + + return size; + } + + return 0; +} + +} // namespace __asan + +using namespace __asan; + +SANITIZER_INTERFACE_ATTRIBUTE +uptr __asan_get_alloc_stack(uptr addr, uptr *trace, uptr size, u32 *thread_id) { + return AsanGetStack(addr, trace, size, thread_id, /* alloc_stack */ true); +} + +SANITIZER_INTERFACE_ATTRIBUTE +uptr __asan_get_free_stack(uptr addr, uptr *trace, uptr size, u32 *thread_id) { + return AsanGetStack(addr, trace, size, thread_id, /* alloc_stack */ false); +} + +SANITIZER_INTERFACE_ATTRIBUTE +void __asan_get_shadow_mapping(uptr *shadow_scale, uptr *shadow_offset) { + if (shadow_scale) + *shadow_scale = SHADOW_SCALE; + if (shadow_offset) + *shadow_offset = SHADOW_OFFSET; +} |

