diff options
author | Alex Shlyapnikov <alekseys@google.com> | 2017-06-22 00:02:37 +0000 |
---|---|---|
committer | Alex Shlyapnikov <alekseys@google.com> | 2017-06-22 00:02:37 +0000 |
commit | 712a9e568d79c2d7e424a60e8cdadf4d6b58e5fc (patch) | |
tree | d7bebe1079ff47be0ba3397ad164dce6fb10be1a /lib/sanitizer_common/sanitizer_win.cc | |
parent | ef55de50c1c83559a70bccfe6439c7b8284e2b75 (diff) |
[Sanitizers] 32 bit allocator respects allocator_may_return_null flag
Summary:
Make SizeClassAllocator32 return nullptr when it encounters OOM, which
allows the entire sanitizer's allocator to follow allocator_may_return_null=1
policy, even for small allocations (LargeMmapAllocator is already fixed
by D34243).
Will add a test for OOM in primary allocator later, when
SizeClassAllocator64 can gracefully handle OOM too.
Reviewers: eugenis
Subscribers: kubamracek, llvm-commits
Differential Revision: https://reviews.llvm.org/D34433
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@305972 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common/sanitizer_win.cc')
-rw-r--r-- | lib/sanitizer_common/sanitizer_win.cc | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/lib/sanitizer_common/sanitizer_win.cc b/lib/sanitizer_common/sanitizer_win.cc index 40800c158..c6a146553 100644 --- a/lib/sanitizer_common/sanitizer_win.cc +++ b/lib/sanitizer_common/sanitizer_win.cc @@ -131,18 +131,24 @@ void UnmapOrDie(void *addr, uptr size) { } } +static void *ReturnNullptrOnOOMOrDie(uptr size, const char *mem_type, + const char *mmap_type) { + error_t last_error = GetLastError(); + if (last_error == ERROR_NOT_ENOUGH_MEMORY) + return nullptr; + ReportMmapFailureAndDie(size, mem_type, mmap_type, last_error); +} + void *MmapOrDieOnFatalError(uptr size, const char *mem_type) { void *rv = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); - if (rv == 0) { - error_t last_error = GetLastError(); - if (last_error != ERROR_NOT_ENOUGH_MEMORY) - ReportMmapFailureAndDie(size, mem_type, "allocate", last_error); - } + if (rv == 0) + return ReturnNullptrOnOOMOrDie(size, mem_type, "allocate"); return rv; } // We want to map a chunk of address space aligned to 'alignment'. -void *MmapAlignedOrDie(uptr size, uptr alignment, const char *mem_type) { +void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment, + const char *mem_type) { CHECK(IsPowerOfTwo(size)); CHECK(IsPowerOfTwo(alignment)); @@ -152,7 +158,7 @@ void *MmapAlignedOrDie(uptr size, uptr alignment, const char *mem_type) { uptr mapped_addr = (uptr)VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (!mapped_addr) - ReportMmapFailureAndDie(size, mem_type, "allocate aligned", GetLastError()); + return ReturnNullptrOnOOMOrDie(size, mem_type, "allocate aligned"); // If we got it right on the first try, return. Otherwise, unmap it and go to // the slow path. @@ -172,8 +178,7 @@ void *MmapAlignedOrDie(uptr size, uptr alignment, const char *mem_type) { mapped_addr = (uptr)VirtualAlloc(0, size + alignment, MEM_RESERVE, PAGE_NOACCESS); if (!mapped_addr) - ReportMmapFailureAndDie(size, mem_type, "allocate aligned", - GetLastError()); + return ReturnNullptrOnOOMOrDie(size, mem_type, "allocate aligned"); // Find the aligned address. uptr aligned_addr = RoundUpTo(mapped_addr, alignment); @@ -191,7 +196,7 @@ void *MmapAlignedOrDie(uptr size, uptr alignment, const char *mem_type) { // Fail if we can't make this work quickly. if (retries == kMaxRetries && mapped_addr == 0) - ReportMmapFailureAndDie(size, mem_type, "allocate aligned", GetLastError()); + return ReturnNullptrOnOOMOrDie(size, mem_type, "allocate aligned"); return (void *)mapped_addr; } |