https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/77168
>From d4953b7a14dfb1d351b543e2546d710ae30173ed Mon Sep 17 00:00:00 2001 From: Vitaly Buka <vitalyb...@google.com> Date: Fri, 5 Jan 2024 18:42:43 -0800 Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?= =?UTF-8?q?itial=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.4 --- compiler-rt/lib/msan/msan.h | 3 ++ compiler-rt/lib/msan/msan_allocator.cpp | 29 ++++++++++++------- compiler-rt/lib/msan/msan_new_delete.cpp | 26 ++++++++++------- .../TestCases/max_allocation_size.cpp | 10 ++++++- 4 files changed, 47 insertions(+), 21 deletions(-) diff --git a/compiler-rt/lib/msan/msan.h b/compiler-rt/lib/msan/msan.h index 25fa2212bdadd3..b717161577a1db 100644 --- a/compiler-rt/lib/msan/msan.h +++ b/compiler-rt/lib/msan/msan.h @@ -321,6 +321,9 @@ const int STACK_TRACE_TAG_VPTR = STACK_TRACE_TAG_FIELDS + 1; stack.Unwind(pc, bp, nullptr, common_flags()->fast_unwind_on_fatal); \ } +#define GET_FATAL_STACK_TRACE \ + GET_FATAL_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME()) + class ScopedThreadLocalStateBackup { public: ScopedThreadLocalStateBackup() { Backup(); } diff --git a/compiler-rt/lib/msan/msan_allocator.cpp b/compiler-rt/lib/msan/msan_allocator.cpp index 72a7f980d39fb0..f71f59cedf820e 100644 --- a/compiler-rt/lib/msan/msan_allocator.cpp +++ b/compiler-rt/lib/msan/msan_allocator.cpp @@ -180,17 +180,19 @@ void MsanThreadLocalMallocStorage::CommitBack() { static void *MsanAllocate(StackTrace *stack, uptr size, uptr alignment, bool zeroise) { - if (size > max_malloc_size) { + if (UNLIKELY(size > max_malloc_size)) { if (AllocatorMayReturnNull()) { Report("WARNING: MemorySanitizer failed to allocate 0x%zx bytes\n", size); return nullptr; } - ReportAllocationSizeTooBig(size, max_malloc_size, stack); + GET_FATAL_STACK_TRACE; + ReportAllocationSizeTooBig(size, max_malloc_size, &stack); } if (UNLIKELY(IsRssLimitExceeded())) { if (AllocatorMayReturnNull()) return nullptr; - ReportRssLimitExceeded(stack); + GET_FATAL_STACK_TRACE; + ReportRssLimitExceeded(&stack); } MsanThread *t = GetCurrentThread(); void *allocated; @@ -206,7 +208,8 @@ static void *MsanAllocate(StackTrace *stack, uptr size, uptr alignment, SetAllocatorOutOfMemory(); if (AllocatorMayReturnNull()) return nullptr; - ReportOutOfMemory(size, stack); + GET_FATAL_STACK_TRACE; + ReportOutOfMemory(size, &stack); } Metadata *meta = reinterpret_cast<Metadata *>(allocator.GetMetaData(allocated)); @@ -288,7 +291,8 @@ static void *MsanCalloc(StackTrace *stack, uptr nmemb, uptr size) { if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) { if (AllocatorMayReturnNull()) return nullptr; - ReportCallocOverflow(nmemb, size, stack); + GET_FATAL_STACK_TRACE; + ReportCallocOverflow(nmemb, size, &stack); } return MsanAllocate(stack, nmemb * size, sizeof(u64), true); } @@ -343,7 +347,8 @@ void *msan_reallocarray(void *ptr, uptr nmemb, uptr size, StackTrace *stack) { errno = errno_ENOMEM; if (AllocatorMayReturnNull()) return nullptr; - ReportReallocArrayOverflow(nmemb, size, stack); + GET_FATAL_STACK_TRACE; + ReportReallocArrayOverflow(nmemb, size, &stack); } return msan_realloc(ptr, nmemb * size, stack); } @@ -358,7 +363,8 @@ void *msan_pvalloc(uptr size, StackTrace *stack) { errno = errno_ENOMEM; if (AllocatorMayReturnNull()) return nullptr; - ReportPvallocOverflow(size, stack); + GET_FATAL_STACK_TRACE; + ReportPvallocOverflow(size, &stack); } // pvalloc(0) should allocate one page. size = size ? RoundUpTo(size, PageSize) : PageSize; @@ -370,7 +376,8 @@ void *msan_aligned_alloc(uptr alignment, uptr size, StackTrace *stack) { errno = errno_EINVAL; if (AllocatorMayReturnNull()) return nullptr; - ReportInvalidAlignedAllocAlignment(size, alignment, stack); + GET_FATAL_STACK_TRACE; + ReportInvalidAlignedAllocAlignment(size, alignment, &stack); } return SetErrnoOnNull(MsanAllocate(stack, size, alignment, false)); } @@ -380,7 +387,8 @@ void *msan_memalign(uptr alignment, uptr size, StackTrace *stack) { errno = errno_EINVAL; if (AllocatorMayReturnNull()) return nullptr; - ReportInvalidAllocationAlignment(alignment, stack); + GET_FATAL_STACK_TRACE; + ReportInvalidAllocationAlignment(alignment, &stack); } return SetErrnoOnNull(MsanAllocate(stack, size, alignment, false)); } @@ -390,7 +398,8 @@ int msan_posix_memalign(void **memptr, uptr alignment, uptr size, if (UNLIKELY(!CheckPosixMemalignAlignment(alignment))) { if (AllocatorMayReturnNull()) return errno_EINVAL; - ReportInvalidPosixMemalignAlignment(alignment, stack); + GET_FATAL_STACK_TRACE; + ReportInvalidPosixMemalignAlignment(alignment, &stack); } void *ptr = MsanAllocate(stack, size, alignment, false); if (UNLIKELY(!ptr)) diff --git a/compiler-rt/lib/msan/msan_new_delete.cpp b/compiler-rt/lib/msan/msan_new_delete.cpp index d4e95c0f65137d..3329a05cca2a86 100644 --- a/compiler-rt/lib/msan/msan_new_delete.cpp +++ b/compiler-rt/lib/msan/msan_new_delete.cpp @@ -30,16 +30,22 @@ namespace std { // TODO(alekseys): throw std::bad_alloc instead of dying on OOM. -#define OPERATOR_NEW_BODY(nothrow) \ - GET_MALLOC_STACK_TRACE; \ - void *res = msan_malloc(size, &stack);\ - if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\ - return res -#define OPERATOR_NEW_BODY_ALIGN(nothrow) \ - GET_MALLOC_STACK_TRACE;\ - void *res = msan_memalign((uptr)align, size, &stack);\ - if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\ - return res; +# define OPERATOR_NEW_BODY(nothrow) \ + GET_MALLOC_STACK_TRACE; \ + void *res = msan_malloc(size, &stack); \ + if (!nothrow && UNLIKELY(!res)) { \ + GET_FATAL_STACK_TRACE; \ + ReportOutOfMemory(size, &stack); \ + } \ + return res +# define OPERATOR_NEW_BODY_ALIGN(nothrow) \ + GET_MALLOC_STACK_TRACE; \ + void *res = msan_memalign((uptr)align, size, &stack); \ + if (!nothrow && UNLIKELY(!res)) { \ + GET_FATAL_STACK_TRACE; \ + ReportOutOfMemory(size, &stack); \ + } \ + return res; INTERCEPTOR_ATTRIBUTE void *operator new(size_t size) { OPERATOR_NEW_BODY(false /*nothrow*/); } diff --git a/compiler-rt/test/sanitizer_common/TestCases/max_allocation_size.cpp b/compiler-rt/test/sanitizer_common/TestCases/max_allocation_size.cpp index ace28965f3c1ba..c74f241c32b754 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/max_allocation_size.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/max_allocation_size.cpp @@ -35,7 +35,7 @@ // RUN: | FileCheck %s --check-prefix=CHECK-nnCRASH // RUN: %env_tool_opts=max_allocation_size_mb=2:allocator_may_return_null=1 \ // RUN: %run %t new-nothrow 2>&1 | FileCheck %s --check-prefix=CHECK-NULL -// RUN: %env_tool_opts=max_allocation_size_mb=2:allocator_may_return_null=0 \ +// RUN: %env_tool_opts=max_allocation_size_mb=2:allocator_may_return_null=0:fast_unwind_on_malloc=0 \ // RUN: not %run %t strndup 2>&1 | FileCheck %s --check-prefix=CHECK-sCRASH // RUN: %env_tool_opts=max_allocation_size_mb=2:allocator_may_return_null=1 \ // RUN: %run %t strndup 2>&1 | FileCheck %s --check-prefix=CHECK-NULL @@ -123,20 +123,28 @@ int main(int Argc, char **Argv) { } // CHECK-mCRASH: malloc: +// CHECK-mCRASH: #{{[0-9]+.*}}max_allocation_size.cpp // CHECK-mCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} // CHECK-cCRASH: calloc: +// CHECK-cCRASH: #{{[0-9]+.*}}max_allocation_size.cpp // CHECK-cCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} // CHECK-rCRASH: realloc: +// CHECK-rCRASH: #{{[0-9]+.*}}max_allocation_size.cpp // CHECK-rCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} // CHECK-mrCRASH: realloc-after-malloc: +// CHECK-mrCRASH: #{{[0-9]+.*}}max_allocation_size.cpp // CHECK-mrCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} // CHECK-nCRASH: new: +// CHECK-nCRASH: #{{[0-9]+.*}}max_allocation_size.cpp // CHECK-nCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} // CHECK-nCRASH-OOM: new: +// CHECK-nCRASH-OOM: #{{[0-9]+.*}}max_allocation_size.cpp // CHECK-nCRASH-OOM: {{SUMMARY: .*Sanitizer: out-of-memory}} // CHECK-nnCRASH: new-nothrow: +// CHECK-nnCRASH: #{{[0-9]+.*}}max_allocation_size.cpp // CHECK-nnCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} // CHECK-sCRASH: strndup: +// CHECK-sCRASH: #{{[0-9]+.*}}max_allocation_size.cpp // CHECK-sCRASH: {{SUMMARY: .*Sanitizer: allocation-size-too-big}} // CHECK-NULL: {{malloc|calloc|calloc-overflow|realloc|realloc-after-malloc|new-nothrow|strndup}} >From 6496ace3246f993e711cc6ab757d2d8c4e4f16f0 Mon Sep 17 00:00:00 2001 From: Vitaly Buka <vitalyb...@google.com> Date: Mon, 8 Jan 2024 11:26:10 -0800 Subject: [PATCH 2/2] comment Created using spr 1.3.4 --- compiler-rt/lib/msan/msan_allocator.cpp | 24 ++++++++++++-------- compiler-rt/lib/msan/msan_new_delete.cpp | 28 ++++++++++++------------ 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/compiler-rt/lib/msan/msan_allocator.cpp b/compiler-rt/lib/msan/msan_allocator.cpp index f71f59cedf820e..bd05799b0b6fda 100644 --- a/compiler-rt/lib/msan/msan_allocator.cpp +++ b/compiler-rt/lib/msan/msan_allocator.cpp @@ -178,6 +178,10 @@ void MsanThreadLocalMallocStorage::CommitBack() { allocator.DestroyCache(GetAllocatorCache(this)); } +// Unwind the stack for fatal error, as the parameter `stack` is +// empty without origins. +#define GET_FATAL_STACK_TRACE MSAN_GET_FATAL_STACK_TRACE_AGAIN + static void *MsanAllocate(StackTrace *stack, uptr size, uptr alignment, bool zeroise) { if (UNLIKELY(size > max_malloc_size)) { @@ -185,13 +189,13 @@ static void *MsanAllocate(StackTrace *stack, uptr size, uptr alignment, Report("WARNING: MemorySanitizer failed to allocate 0x%zx bytes\n", size); return nullptr; } - GET_FATAL_STACK_TRACE; + MSAN_GET_FATAL_STACK_TRACE_AGAIN; ReportAllocationSizeTooBig(size, max_malloc_size, &stack); } if (UNLIKELY(IsRssLimitExceeded())) { if (AllocatorMayReturnNull()) return nullptr; - GET_FATAL_STACK_TRACE; + MSAN_GET_FATAL_STACK_TRACE_AGAIN; ReportRssLimitExceeded(&stack); } MsanThread *t = GetCurrentThread(); @@ -208,7 +212,7 @@ static void *MsanAllocate(StackTrace *stack, uptr size, uptr alignment, SetAllocatorOutOfMemory(); if (AllocatorMayReturnNull()) return nullptr; - GET_FATAL_STACK_TRACE; + MSAN_GET_FATAL_STACK_TRACE_AGAIN; ReportOutOfMemory(size, &stack); } Metadata *meta = @@ -291,7 +295,7 @@ static void *MsanCalloc(StackTrace *stack, uptr nmemb, uptr size) { if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) { if (AllocatorMayReturnNull()) return nullptr; - GET_FATAL_STACK_TRACE; + MSAN_GET_FATAL_STACK_TRACE_AGAIN; ReportCallocOverflow(nmemb, size, &stack); } return MsanAllocate(stack, nmemb * size, sizeof(u64), true); @@ -347,7 +351,7 @@ void *msan_reallocarray(void *ptr, uptr nmemb, uptr size, StackTrace *stack) { errno = errno_ENOMEM; if (AllocatorMayReturnNull()) return nullptr; - GET_FATAL_STACK_TRACE; + MSAN_GET_FATAL_STACK_TRACE_AGAIN; ReportReallocArrayOverflow(nmemb, size, &stack); } return msan_realloc(ptr, nmemb * size, stack); @@ -363,7 +367,7 @@ void *msan_pvalloc(uptr size, StackTrace *stack) { errno = errno_ENOMEM; if (AllocatorMayReturnNull()) return nullptr; - GET_FATAL_STACK_TRACE; + MSAN_GET_FATAL_STACK_TRACE_AGAIN; ReportPvallocOverflow(size, &stack); } // pvalloc(0) should allocate one page. @@ -376,7 +380,7 @@ void *msan_aligned_alloc(uptr alignment, uptr size, StackTrace *stack) { errno = errno_EINVAL; if (AllocatorMayReturnNull()) return nullptr; - GET_FATAL_STACK_TRACE; + MSAN_GET_FATAL_STACK_TRACE_AGAIN; ReportInvalidAlignedAllocAlignment(size, alignment, &stack); } return SetErrnoOnNull(MsanAllocate(stack, size, alignment, false)); @@ -387,7 +391,7 @@ void *msan_memalign(uptr alignment, uptr size, StackTrace *stack) { errno = errno_EINVAL; if (AllocatorMayReturnNull()) return nullptr; - GET_FATAL_STACK_TRACE; + MSAN_GET_FATAL_STACK_TRACE_AGAIN; ReportInvalidAllocationAlignment(alignment, &stack); } return SetErrnoOnNull(MsanAllocate(stack, size, alignment, false)); @@ -398,7 +402,7 @@ int msan_posix_memalign(void **memptr, uptr alignment, uptr size, if (UNLIKELY(!CheckPosixMemalignAlignment(alignment))) { if (AllocatorMayReturnNull()) return errno_EINVAL; - GET_FATAL_STACK_TRACE; + MSAN_GET_FATAL_STACK_TRACE_AGAIN; ReportInvalidPosixMemalignAlignment(alignment, &stack); } void *ptr = MsanAllocate(stack, size, alignment, false); @@ -410,6 +414,8 @@ int msan_posix_memalign(void **memptr, uptr alignment, uptr size, return 0; } +#undef MSAN_GET_FATAL_STACK_TRACE_AGAIN + } // namespace __msan using namespace __msan; diff --git a/compiler-rt/lib/msan/msan_new_delete.cpp b/compiler-rt/lib/msan/msan_new_delete.cpp index 3329a05cca2a86..9f5a4b2d38b256 100644 --- a/compiler-rt/lib/msan/msan_new_delete.cpp +++ b/compiler-rt/lib/msan/msan_new_delete.cpp @@ -30,21 +30,21 @@ namespace std { // TODO(alekseys): throw std::bad_alloc instead of dying on OOM. -# define OPERATOR_NEW_BODY(nothrow) \ - GET_MALLOC_STACK_TRACE; \ - void *res = msan_malloc(size, &stack); \ - if (!nothrow && UNLIKELY(!res)) { \ - GET_FATAL_STACK_TRACE; \ - ReportOutOfMemory(size, &stack); \ - } \ +# define OPERATOR_NEW_BODY(nothrow) \ + GET_MALLOC_STACK_TRACE; \ + void *res = msan_malloc(size, &stack); \ + if (!nothrow && UNLIKELY(!res)) { \ + GET_FATAL_STACK_TRACE; /* see `MSAN_GET_FATAL_STACK_TRACE_AGAIN` */ \ + ReportOutOfMemory(size, &stack); \ + } \ return res -# define OPERATOR_NEW_BODY_ALIGN(nothrow) \ - GET_MALLOC_STACK_TRACE; \ - void *res = msan_memalign((uptr)align, size, &stack); \ - if (!nothrow && UNLIKELY(!res)) { \ - GET_FATAL_STACK_TRACE; \ - ReportOutOfMemory(size, &stack); \ - } \ +# define OPERATOR_NEW_BODY_ALIGN(nothrow) \ + GET_MALLOC_STACK_TRACE; /* see `MSAN_GET_FATAL_STACK_TRACE_AGAIN` */ \ + void *res = msan_memalign((uptr)align, size, &stack); \ + if (!nothrow && UNLIKELY(!res)) { \ + GET_FATAL_STACK_TRACE; \ + ReportOutOfMemory(size, &stack); \ + } \ return res; INTERCEPTOR_ATTRIBUTE _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits