[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:
Leonard Chan 2022-06-07 16:45:01 -07:00
parent 5368c685d9
commit e1d84c421d
9 changed files with 34 additions and 10 deletions

View file

@ -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();

View file

@ -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();
}

View file

@ -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

View file

@ -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);

View file

@ -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());

View file

@ -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,

View file

@ -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)

View file

@ -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

View file

@ -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).