From cc9aad0498fccd587a4c697701446d952c69e557 Mon Sep 17 00:00:00 2001 From: Vyacheslav Cherkashin Date: Wed, 12 Dec 2018 18:11:52 +0300 Subject: [PATCH] [LSan] Export a LSan API for use it third party This API is needed to use LSan in conjunction with SWAP Change-Id: Iff1ceaca9242a889b0b68f672302f8a0b3808411 Signed-off-by: Vyacheslav Cherkashin --- libsanitizer/include/sanitizer/lsan_interface.h | 19 ++++++++++++++++ libsanitizer/lsan/lsan.cc | 5 +++++ libsanitizer/lsan/lsan.h | 15 ++++++++++--- libsanitizer/lsan/lsan_allocator.cc | 26 ++++++++++++++++++++++ .../sanitizer_allocator_combined.h | 2 +- 5 files changed, 63 insertions(+), 4 deletions(-) diff --git a/libsanitizer/include/sanitizer/lsan_interface.h b/libsanitizer/include/sanitizer/lsan_interface.h index bdbe390..7cdffda 100644 --- a/libsanitizer/include/sanitizer/lsan_interface.h +++ b/libsanitizer/include/sanitizer/lsan_interface.h @@ -67,6 +67,25 @@ extern "C" { // This function may be optionally provided by the user and should return // a string containing LSan suppressions. const char *__lsan_default_suppressions(); + + // Check a pointer belongs to the LSan allocator. + // 0 - not belong + // 1 - belong + int __lsan_allocator_pointer_is_mine(const void *p); + + // Allocate memory using LSan allocator. + void *__lsan_allocator_allocate(size_t size, size_t alignment, int cleared, + unsigned long caller_pc, unsigned long frame); + + // Deallocate memory using LSan allocator. + void __lsan_allocator_deallocate(void *p); + + // Reallocate memory using LSan allocator. + void *__lsan_allocator_reallocate(void *p, size_t new_size, size_t alignment, + unsigned long caller_pc, unsigned long frame); + + // Get LSan report file. + const char *__lsan_report_file(); #ifdef __cplusplus } // extern "C" diff --git a/libsanitizer/lsan/lsan.cc b/libsanitizer/lsan/lsan.cc index 6b68c61..b306734 100644 --- a/libsanitizer/lsan/lsan.cc +++ b/libsanitizer/lsan/lsan.cc @@ -121,3 +121,8 @@ void __sanitizer_print_stack_trace() { GET_STACK_TRACE_FATAL; stack.Print(); } + +extern "C" SANITIZER_INTERFACE_ATTRIBUTE +const char *__lsan_report_file() { + return report_file.full_path; +} diff --git a/libsanitizer/lsan/lsan.h b/libsanitizer/lsan/lsan.h index 881958e..4b4ede73 100644 --- a/libsanitizer/lsan/lsan.h +++ b/libsanitizer/lsan/lsan.h @@ -10,10 +10,11 @@ // //===----------------------------------------------------------------------===// +#include "lsan_thread.h" #include "sanitizer_common/sanitizer_flags.h" #include "sanitizer_common/sanitizer_stacktrace.h" -#define GET_STACK_TRACE(max_size, fast) \ +#define GET_STACK_TRACE_RAW(caller_pc, frame, max_size, fast) \ BufferedStackTrace stack; \ { \ uptr stack_top = 0, stack_bottom = 0; \ @@ -23,12 +24,15 @@ stack_bottom = t->stack_begin(); \ } \ if (!SANITIZER_MIPS || \ - IsValidFrame(GET_CURRENT_FRAME(), stack_top, stack_bottom)) { \ - stack.Unwind(max_size, StackTrace::GetCurrentPc(), GET_CURRENT_FRAME(), \ + IsValidFrame(frame, stack_top, stack_bottom)) { \ + stack.Unwind(max_size, caller_pc, frame, \ /* context */ 0, stack_top, stack_bottom, fast); \ } \ } +#define GET_STACK_TRACE(max_size, fast) \ + GET_STACK_TRACE_RAW(GET_CALLER_PC(), GET_CURRENT_FRAME(), max_size, fast) + #define GET_STACK_TRACE_FATAL \ GET_STACK_TRACE(kStackTraceMax, common_flags()->fast_unwind_on_fatal) @@ -36,6 +40,11 @@ GET_STACK_TRACE(__sanitizer::common_flags()->malloc_context_size, \ common_flags()->fast_unwind_on_malloc) +#define GET_STACK_TRACE_MALLOC_RAW(caller_pc, frame) \ + GET_STACK_TRACE_RAW(caller_pc, frame, \ + __sanitizer::common_flags()->malloc_context_size, \ + common_flags()->fast_unwind_on_malloc) + #ifndef LSAN_DYNAMIC # ifdef PIC # define LSAN_DYNAMIC 1 diff --git a/libsanitizer/lsan/lsan_allocator.cc b/libsanitizer/lsan/lsan_allocator.cc index 00b6a15..a20d1eb 100644 --- a/libsanitizer/lsan/lsan_allocator.cc +++ b/libsanitizer/lsan/lsan_allocator.cc @@ -19,6 +19,7 @@ #include "sanitizer_common/sanitizer_stacktrace.h" #include "sanitizer_common/sanitizer_allocator_internal.h" #include "lsan_common.h" +#include "lsan.h" extern "C" void *memset(void *ptr, int value, uptr num); @@ -284,4 +285,29 @@ SANITIZER_INTERFACE_ATTRIBUTE uptr __sanitizer_get_allocated_size(const void *p) { return GetMallocUsableSize(p); } + +// LSan allocator API +SANITIZER_INTERFACE_ATTRIBUTE +int __lsan_allocator_pointer_is_mine(const void *p) { + return allocator.PointerIsMine(p); +} + +SANITIZER_INTERFACE_ATTRIBUTE +void *__lsan_allocator_allocate(uptr size, uptr alignment, int cleared, + unsigned long caller_pc, unsigned long frame) { + GET_STACK_TRACE_MALLOC_RAW(caller_pc, frame); + return Allocate(stack, size, alignment, cleared); +} + +SANITIZER_INTERFACE_ATTRIBUTE +void __lsan_allocator_deallocate(void *p) { + Deallocate(p); +} + +SANITIZER_INTERFACE_ATTRIBUTE +void *__lsan_allocator_reallocate(void *p, uptr new_size, uptr alignment, + unsigned long caller_pc, unsigned long frame) { + GET_STACK_TRACE_MALLOC_RAW(caller_pc, frame); + return Reallocate(stack, p, new_size, alignment); +} } // extern "C" diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_combined.h b/libsanitizer/sanitizer_common/sanitizer_allocator_combined.h index 3b408d5..118a6aa 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_combined.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_combined.h @@ -101,7 +101,7 @@ class CombinedAllocator { return new_p; } - bool PointerIsMine(void *p) { + bool PointerIsMine(const void *p) { if (primary_.PointerIsMine(p)) return true; return secondary_.PointerIsMine(p); -- 2.7.4