168d75effSDimitry Andric //===-- sanitizer_allocator_report.cpp --------------------------*- C++ -*-===//
268d75effSDimitry Andric //
368d75effSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
468d75effSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
568d75effSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
668d75effSDimitry Andric //
768d75effSDimitry Andric //===----------------------------------------------------------------------===//
868d75effSDimitry Andric ///
968d75effSDimitry Andric /// \file
1068d75effSDimitry Andric /// Shared allocator error reporting for ThreadSanitizer, MemorySanitizer, etc.
1168d75effSDimitry Andric ///
1268d75effSDimitry Andric //===----------------------------------------------------------------------===//
1368d75effSDimitry Andric 
1468d75effSDimitry Andric #include "sanitizer_allocator.h"
1568d75effSDimitry Andric #include "sanitizer_allocator_report.h"
1668d75effSDimitry Andric #include "sanitizer_common.h"
1768d75effSDimitry Andric #include "sanitizer_report_decorator.h"
1868d75effSDimitry Andric 
1968d75effSDimitry Andric namespace __sanitizer {
2068d75effSDimitry Andric 
2168d75effSDimitry Andric class ScopedAllocatorErrorReport {
2268d75effSDimitry Andric  public:
ScopedAllocatorErrorReport(const char * error_summary_,const StackTrace * stack_)2368d75effSDimitry Andric   ScopedAllocatorErrorReport(const char *error_summary_,
2468d75effSDimitry Andric                              const StackTrace *stack_)
2568d75effSDimitry Andric       : error_summary(error_summary_),
2668d75effSDimitry Andric         stack(stack_) {
2768d75effSDimitry Andric     Printf("%s", d.Error());
2868d75effSDimitry Andric   }
~ScopedAllocatorErrorReport()2968d75effSDimitry Andric   ~ScopedAllocatorErrorReport() {
3068d75effSDimitry Andric     Printf("%s", d.Default());
3168d75effSDimitry Andric     stack->Print();
3268d75effSDimitry Andric     PrintHintAllocatorCannotReturnNull();
3368d75effSDimitry Andric     ReportErrorSummary(error_summary, stack);
3468d75effSDimitry Andric   }
3568d75effSDimitry Andric 
3668d75effSDimitry Andric  private:
3768d75effSDimitry Andric   ScopedErrorReportLock lock;
3868d75effSDimitry Andric   const char *error_summary;
3968d75effSDimitry Andric   const StackTrace* const stack;
4068d75effSDimitry Andric   const SanitizerCommonDecorator d;
4168d75effSDimitry Andric };
4268d75effSDimitry Andric 
ReportCallocOverflow(uptr count,uptr size,const StackTrace * stack)4368d75effSDimitry Andric void NORETURN ReportCallocOverflow(uptr count, uptr size,
4468d75effSDimitry Andric                                    const StackTrace *stack) {
4568d75effSDimitry Andric   {
4668d75effSDimitry Andric     ScopedAllocatorErrorReport report("calloc-overflow", stack);
4768d75effSDimitry Andric     Report("ERROR: %s: calloc parameters overflow: count * size (%zd * %zd) "
4868d75effSDimitry Andric            "cannot be represented in type size_t\n", SanitizerToolName, count,
4968d75effSDimitry Andric            size);
5068d75effSDimitry Andric   }
5168d75effSDimitry Andric   Die();
5268d75effSDimitry Andric }
5368d75effSDimitry Andric 
ReportReallocArrayOverflow(uptr count,uptr size,const StackTrace * stack)5468d75effSDimitry Andric void NORETURN ReportReallocArrayOverflow(uptr count, uptr size,
5568d75effSDimitry Andric                                          const StackTrace *stack) {
5668d75effSDimitry Andric   {
5768d75effSDimitry Andric     ScopedAllocatorErrorReport report("reallocarray-overflow", stack);
5868d75effSDimitry Andric     Report(
5968d75effSDimitry Andric         "ERROR: %s: reallocarray parameters overflow: count * size (%zd * %zd) "
6068d75effSDimitry Andric         "cannot be represented in type size_t\n",
6168d75effSDimitry Andric         SanitizerToolName, count, size);
6268d75effSDimitry Andric   }
6368d75effSDimitry Andric   Die();
6468d75effSDimitry Andric }
6568d75effSDimitry Andric 
ReportPvallocOverflow(uptr size,const StackTrace * stack)6668d75effSDimitry Andric void NORETURN ReportPvallocOverflow(uptr size, const StackTrace *stack) {
6768d75effSDimitry Andric   {
6868d75effSDimitry Andric     ScopedAllocatorErrorReport report("pvalloc-overflow", stack);
6968d75effSDimitry Andric     Report("ERROR: %s: pvalloc parameters overflow: size 0x%zx rounded up to "
7068d75effSDimitry Andric            "system page size 0x%zx cannot be represented in type size_t\n",
7168d75effSDimitry Andric            SanitizerToolName, size, GetPageSizeCached());
7268d75effSDimitry Andric   }
7368d75effSDimitry Andric   Die();
7468d75effSDimitry Andric }
7568d75effSDimitry Andric 
ReportInvalidAllocationAlignment(uptr alignment,const StackTrace * stack)7668d75effSDimitry Andric void NORETURN ReportInvalidAllocationAlignment(uptr alignment,
7768d75effSDimitry Andric                                                const StackTrace *stack) {
7868d75effSDimitry Andric   {
7968d75effSDimitry Andric     ScopedAllocatorErrorReport report("invalid-allocation-alignment", stack);
8068d75effSDimitry Andric     Report("ERROR: %s: invalid allocation alignment: %zd, alignment must be a "
8168d75effSDimitry Andric            "power of two\n", SanitizerToolName, alignment);
8268d75effSDimitry Andric   }
8368d75effSDimitry Andric   Die();
8468d75effSDimitry Andric }
8568d75effSDimitry Andric 
ReportInvalidAlignedAllocAlignment(uptr size,uptr alignment,const StackTrace * stack)8668d75effSDimitry Andric void NORETURN ReportInvalidAlignedAllocAlignment(uptr size, uptr alignment,
8768d75effSDimitry Andric                                                  const StackTrace *stack) {
8868d75effSDimitry Andric   {
8968d75effSDimitry Andric     ScopedAllocatorErrorReport report("invalid-aligned-alloc-alignment", stack);
9068d75effSDimitry Andric #if SANITIZER_POSIX
9168d75effSDimitry Andric     Report("ERROR: %s: invalid alignment requested in "
9268d75effSDimitry Andric            "aligned_alloc: %zd, alignment must be a power of two and the "
9368d75effSDimitry Andric            "requested size 0x%zx must be a multiple of alignment\n",
9468d75effSDimitry Andric            SanitizerToolName, alignment, size);
9568d75effSDimitry Andric #else
9668d75effSDimitry Andric     Report("ERROR: %s: invalid alignment requested in aligned_alloc: %zd, "
9768d75effSDimitry Andric            "the requested size 0x%zx must be a multiple of alignment\n",
9868d75effSDimitry Andric            SanitizerToolName, alignment, size);
9968d75effSDimitry Andric #endif
10068d75effSDimitry Andric   }
10168d75effSDimitry Andric   Die();
10268d75effSDimitry Andric }
10368d75effSDimitry Andric 
ReportInvalidPosixMemalignAlignment(uptr alignment,const StackTrace * stack)10468d75effSDimitry Andric void NORETURN ReportInvalidPosixMemalignAlignment(uptr alignment,
10568d75effSDimitry Andric                                                   const StackTrace *stack) {
10668d75effSDimitry Andric   {
10768d75effSDimitry Andric     ScopedAllocatorErrorReport report("invalid-posix-memalign-alignment",
10868d75effSDimitry Andric                                       stack);
10968d75effSDimitry Andric     Report(
11068d75effSDimitry Andric         "ERROR: %s: invalid alignment requested in "
11168d75effSDimitry Andric         "posix_memalign: %zd, alignment must be a power of two and a "
11268d75effSDimitry Andric         "multiple of sizeof(void*) == %zd\n",
11368d75effSDimitry Andric         SanitizerToolName, alignment, sizeof(void *));
11468d75effSDimitry Andric   }
11568d75effSDimitry Andric   Die();
11668d75effSDimitry Andric }
11768d75effSDimitry Andric 
ReportAllocationSizeTooBig(uptr user_size,uptr max_size,const StackTrace * stack)11868d75effSDimitry Andric void NORETURN ReportAllocationSizeTooBig(uptr user_size, uptr max_size,
11968d75effSDimitry Andric                                          const StackTrace *stack) {
12068d75effSDimitry Andric   {
12168d75effSDimitry Andric     ScopedAllocatorErrorReport report("allocation-size-too-big", stack);
12268d75effSDimitry Andric     Report("ERROR: %s: requested allocation size 0x%zx exceeds maximum "
12368d75effSDimitry Andric            "supported size of 0x%zx\n", SanitizerToolName, user_size, max_size);
12468d75effSDimitry Andric   }
12568d75effSDimitry Andric   Die();
12668d75effSDimitry Andric }
12768d75effSDimitry Andric 
ReportOutOfMemory(uptr requested_size,const StackTrace * stack)12868d75effSDimitry Andric void NORETURN ReportOutOfMemory(uptr requested_size, const StackTrace *stack) {
12968d75effSDimitry Andric   {
13068d75effSDimitry Andric     ScopedAllocatorErrorReport report("out-of-memory", stack);
131*81ad6265SDimitry Andric     ERROR_OOM("allocator is trying to allocate 0x%zx bytes\n", requested_size);
13268d75effSDimitry Andric   }
13368d75effSDimitry Andric   Die();
13468d75effSDimitry Andric }
13568d75effSDimitry Andric 
ReportRssLimitExceeded(const StackTrace * stack)136e8d8bef9SDimitry Andric void NORETURN ReportRssLimitExceeded(const StackTrace *stack) {
137e8d8bef9SDimitry Andric   {
138e8d8bef9SDimitry Andric     ScopedAllocatorErrorReport report("rss-limit-exceeded", stack);
139e8d8bef9SDimitry Andric     Report("ERROR: %s: allocator exceeded the RSS limit\n", SanitizerToolName);
140e8d8bef9SDimitry Andric   }
141e8d8bef9SDimitry Andric   Die();
142e8d8bef9SDimitry Andric }
143e8d8bef9SDimitry Andric 
14468d75effSDimitry Andric }  // namespace __sanitizer
145