forked from OSchip/llvm-project
[compiler-rt][sanitizer] Have all OOM-related error messages start with the same format
This way downstream tools that read sanitizer output can differentiate between OOM errors reported by sanitizers from other sanitizer errors. Changes: - Introduce ErrorIsOOM for checking if a platform-specific error code from an "mmap" is an OOM err. - Add ReportOOMError which just prepends this error message to the start of a Report call. - Replace some Reports for OOMs with calls to ReportOOMError. - Update necessary tests. Differential Revision: https://reviews.llvm.org/D127161
This commit is contained in:
parent
5368c685d9
commit
e1d84c421d
|
@ -279,9 +279,7 @@ void ErrorRssLimitExceeded::Print() {
|
|||
void ErrorOutOfMemory::Print() {
|
||||
Decorator d;
|
||||
Printf("%s", d.Error());
|
||||
Report(
|
||||
"ERROR: AddressSanitizer: allocator is out of memory trying to allocate "
|
||||
"0x%zx bytes\n", requested_size);
|
||||
ERROR_OOM("allocator is trying to allocate 0x%zx bytes\n", requested_size);
|
||||
Printf("%s", d.Default());
|
||||
stack->Print();
|
||||
PrintHintAllocatorCannotReturnNull();
|
||||
|
|
|
@ -128,8 +128,7 @@ void NORETURN ReportAllocationSizeTooBig(uptr user_size, uptr max_size,
|
|||
void NORETURN ReportOutOfMemory(uptr requested_size, const StackTrace *stack) {
|
||||
{
|
||||
ScopedAllocatorErrorReport report("out-of-memory", stack);
|
||||
Report("ERROR: %s: allocator is out of memory trying to allocate 0x%zx "
|
||||
"bytes\n", SanitizerToolName, requested_size);
|
||||
ERROR_OOM("allocator is trying to allocate 0x%zx bytes\n", requested_size);
|
||||
}
|
||||
Die();
|
||||
}
|
||||
|
|
|
@ -46,9 +46,15 @@ void NORETURN ReportMmapFailureAndDie(uptr size, const char *mem_type,
|
|||
Die();
|
||||
}
|
||||
recursion_count++;
|
||||
Report("ERROR: %s failed to "
|
||||
"%s 0x%zx (%zd) bytes of %s (error code: %d)\n",
|
||||
SanitizerToolName, mmap_type, size, size, mem_type, err);
|
||||
if (ErrorIsOOM(err)) {
|
||||
ERROR_OOM("failed to %s 0x%zx (%zd) bytes of %s (error code: %d)\n",
|
||||
mmap_type, size, size, mem_type, err);
|
||||
} else {
|
||||
Report(
|
||||
"ERROR: %s failed to "
|
||||
"%s 0x%zx (%zd) bytes of %s (error code: %d)\n",
|
||||
SanitizerToolName, mmap_type, size, size, mem_type, err);
|
||||
}
|
||||
#if !SANITIZER_GO
|
||||
DumpProcessMap();
|
||||
#endif
|
||||
|
|
|
@ -311,6 +311,18 @@ void NORETURN ReportMmapFailureAndDie(uptr size, const char *mem_type,
|
|||
const char *mmap_type, error_t err,
|
||||
bool raw_report = false);
|
||||
|
||||
// Returns true if the platform-specific error reported is an OOM error.
|
||||
bool ErrorIsOOM(error_t err);
|
||||
|
||||
// This reports an error in the form:
|
||||
//
|
||||
// `ERROR: {{SanitizerToolName}}: out of memory: {{err_msg}}`
|
||||
//
|
||||
// Downstream tools that read sanitizer output will know that errors starting
|
||||
// in this format are specifically OOM errors.
|
||||
#define ERROR_OOM(err_msg, ...) \
|
||||
Report("ERROR: %s: out of memory: " err_msg, SanitizerToolName, __VA_ARGS__)
|
||||
|
||||
// Specific tools may override behavior of "Die" function to do tool-specific
|
||||
// job.
|
||||
typedef void (*DieCallbackType)(void);
|
||||
|
|
|
@ -128,6 +128,8 @@ uptr GetMaxUserVirtualAddress() {
|
|||
|
||||
uptr GetMaxVirtualAddress() { return GetMaxUserVirtualAddress(); }
|
||||
|
||||
bool ErrorIsOOM(error_t err) { return err == ZX_ERR_NO_MEMORY; }
|
||||
|
||||
static void *DoAnonymousMmapOrDie(uptr size, const char *mem_type,
|
||||
bool raw_report, bool die_for_nomem) {
|
||||
size = RoundUpTo(size, GetPageSize());
|
||||
|
|
|
@ -41,6 +41,8 @@ uptr GetMmapGranularity() {
|
|||
return GetPageSize();
|
||||
}
|
||||
|
||||
bool ErrorIsOOM(error_t err) { return err == ENOMEM; }
|
||||
|
||||
void *MmapOrDie(uptr size, const char *mem_type, bool raw_report) {
|
||||
size = RoundUpTo(size, GetPageSizeCached());
|
||||
uptr res = MmapNamed(nullptr, size, PROT_READ | PROT_WRITE,
|
||||
|
|
|
@ -131,6 +131,11 @@ void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
|
|||
}
|
||||
#endif // #if !SANITIZER_GO
|
||||
|
||||
bool ErrorIsOOM(error_t err) {
|
||||
// TODO: This should check which `err`s correspond to OOM.
|
||||
return false;
|
||||
}
|
||||
|
||||
void *MmapOrDie(uptr size, const char *mem_type, bool raw_report) {
|
||||
void *rv = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||
if (rv == 0)
|
||||
|
|
|
@ -84,6 +84,6 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
// CHECK-max: {{ERROR: HWAddressSanitizer: requested allocation size .* exceeds maximum supported size}}
|
||||
// CHECK-oom: ERROR: HWAddressSanitizer: allocator is out of memory
|
||||
// CHECK-oom: ERROR: HWAddressSanitizer: out of memory: allocator is trying to allocate
|
||||
// CHECK-calloc: ERROR: HWAddressSanitizer: calloc parameters overflow
|
||||
// CHECK-reallocarray: ERROR: HWAddressSanitizer: reallocarray parameters overflow
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// CHECK: {{Leak|Address}}Sanitizer failed to allocate 0x100001 bytes
|
||||
// CHECK: {{Leak|Address}}Sanitizer: out of memory: failed to allocate 0x100001 bytes
|
||||
|
||||
// CHECK: {{Leak|Address}}Sanitizer: detected memory leaks
|
||||
// CHECK: {{Leak|Address}}Sanitizer: 9 byte(s) leaked in 1 allocation(s).
|
||||
|
|
Loading…
Reference in New Issue