1 | //===-- sanitizer_allocator_report.cpp --------------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | /// |
9 | /// \file |
10 | /// Shared allocator error reporting for ThreadSanitizer, MemorySanitizer, etc. |
11 | /// |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #include "sanitizer_allocator.h" |
15 | #include "sanitizer_allocator_report.h" |
16 | #include "sanitizer_common.h" |
17 | #include "sanitizer_report_decorator.h" |
18 | |
19 | namespace __sanitizer { |
20 | |
21 | class ScopedAllocatorErrorReport { |
22 | public: |
23 | ScopedAllocatorErrorReport(const char *error_summary_, |
24 | const StackTrace *stack_) |
25 | : error_summary(error_summary_), |
26 | stack(stack_) { |
27 | Printf(format: "%s" , d.Error()); |
28 | } |
29 | ~ScopedAllocatorErrorReport() { |
30 | Printf(format: "%s" , d.Default()); |
31 | stack->Print(); |
32 | PrintHintAllocatorCannotReturnNull(); |
33 | ReportErrorSummary(error_type: error_summary, trace: stack); |
34 | } |
35 | |
36 | private: |
37 | ScopedErrorReportLock lock; |
38 | const char *error_summary; |
39 | const StackTrace* const stack; |
40 | const SanitizerCommonDecorator d; |
41 | }; |
42 | |
43 | void NORETURN ReportCallocOverflow(uptr count, uptr size, |
44 | const StackTrace *stack) { |
45 | { |
46 | ScopedAllocatorErrorReport report("calloc-overflow" , stack); |
47 | Report(format: "ERROR: %s: calloc parameters overflow: count * size (%zd * %zd) " |
48 | "cannot be represented in type size_t\n" , SanitizerToolName, count, |
49 | size); |
50 | } |
51 | Die(); |
52 | } |
53 | |
54 | void NORETURN ReportReallocArrayOverflow(uptr count, uptr size, |
55 | const StackTrace *stack) { |
56 | { |
57 | ScopedAllocatorErrorReport report("reallocarray-overflow" , stack); |
58 | Report( |
59 | format: "ERROR: %s: reallocarray parameters overflow: count * size (%zd * %zd) " |
60 | "cannot be represented in type size_t\n" , |
61 | SanitizerToolName, count, size); |
62 | } |
63 | Die(); |
64 | } |
65 | |
66 | void NORETURN ReportPvallocOverflow(uptr size, const StackTrace *stack) { |
67 | { |
68 | ScopedAllocatorErrorReport report("pvalloc-overflow" , stack); |
69 | Report(format: "ERROR: %s: pvalloc parameters overflow: size 0x%zx rounded up to " |
70 | "system page size 0x%zx cannot be represented in type size_t\n" , |
71 | SanitizerToolName, size, GetPageSizeCached()); |
72 | } |
73 | Die(); |
74 | } |
75 | |
76 | void NORETURN ReportInvalidAllocationAlignment(uptr alignment, |
77 | const StackTrace *stack) { |
78 | { |
79 | ScopedAllocatorErrorReport report("invalid-allocation-alignment" , stack); |
80 | Report(format: "ERROR: %s: invalid allocation alignment: %zd, alignment must be a " |
81 | "power of two\n" , SanitizerToolName, alignment); |
82 | } |
83 | Die(); |
84 | } |
85 | |
86 | void NORETURN ReportInvalidAlignedAllocAlignment(uptr size, uptr alignment, |
87 | const StackTrace *stack) { |
88 | { |
89 | ScopedAllocatorErrorReport report("invalid-aligned-alloc-alignment" , stack); |
90 | #if SANITIZER_POSIX |
91 | Report(format: "ERROR: %s: invalid alignment requested in " |
92 | "aligned_alloc: %zd, alignment must be a power of two and the " |
93 | "requested size 0x%zx must be a multiple of alignment\n" , |
94 | SanitizerToolName, alignment, size); |
95 | #else |
96 | Report("ERROR: %s: invalid alignment requested in aligned_alloc: %zd, " |
97 | "the requested size 0x%zx must be a multiple of alignment\n" , |
98 | SanitizerToolName, alignment, size); |
99 | #endif |
100 | } |
101 | Die(); |
102 | } |
103 | |
104 | void NORETURN ReportInvalidPosixMemalignAlignment(uptr alignment, |
105 | const StackTrace *stack) { |
106 | { |
107 | ScopedAllocatorErrorReport report("invalid-posix-memalign-alignment" , |
108 | stack); |
109 | Report( |
110 | format: "ERROR: %s: invalid alignment requested in " |
111 | "posix_memalign: %zd, alignment must be a power of two and a " |
112 | "multiple of sizeof(void*) == %zd\n" , |
113 | SanitizerToolName, alignment, sizeof(void *)); |
114 | } |
115 | Die(); |
116 | } |
117 | |
118 | void NORETURN ReportAllocationSizeTooBig(uptr user_size, uptr max_size, |
119 | const StackTrace *stack) { |
120 | { |
121 | ScopedAllocatorErrorReport report("allocation-size-too-big" , stack); |
122 | Report(format: "ERROR: %s: requested allocation size 0x%zx exceeds maximum " |
123 | "supported size of 0x%zx\n" , SanitizerToolName, user_size, max_size); |
124 | } |
125 | Die(); |
126 | } |
127 | |
128 | void NORETURN ReportOutOfMemory(uptr requested_size, const StackTrace *stack) { |
129 | { |
130 | ScopedAllocatorErrorReport report("out-of-memory" , stack); |
131 | ERROR_OOM("allocator is trying to allocate 0x%zx bytes\n" , requested_size); |
132 | } |
133 | Die(); |
134 | } |
135 | |
136 | void NORETURN (const StackTrace *stack) { |
137 | { |
138 | ScopedAllocatorErrorReport report("rss-limit-exceeded" , stack); |
139 | Report(format: "ERROR: %s: allocator exceeded the RSS limit\n" , SanitizerToolName); |
140 | } |
141 | Die(); |
142 | } |
143 | |
144 | } // namespace __sanitizer |
145 | |