linker: CHECK() or async_safe_fatal() rather than abort().
In particular, add the strerror() output if mprotect() fails.
Fix the CHECK macro so that you can make assertions involving operator%
without that being confused for a printf format specifier.
Bug: https://issuetracker.google.com/158645318
Test: treehugger
Change-Id: I6817f8ca5f094c52dc2c9067bfac90385a8743f5
diff --git a/libc/async_safe/include/async_safe/CHECK.h b/libc/async_safe/include/async_safe/CHECK.h
index bec89a3..46d460c 100644
--- a/libc/async_safe/include/async_safe/CHECK.h
+++ b/libc/async_safe/include/async_safe/CHECK.h
@@ -36,12 +36,12 @@
// TODO: replace this with something more like <android-base/logging.h>'s family of macros.
-#define CHECK(predicate) \
- do { \
- if (!(predicate)) { \
- async_safe_fatal("%s:%d: %s CHECK '" #predicate "' failed", \
- __FILE__, __LINE__, __FUNCTION__); \
- } \
- } while(0)
+#define CHECK(predicate) \
+ do { \
+ if (!(predicate)) { \
+ async_safe_fatal("%s:%d: %s CHECK '%s' failed", __FILE__, __LINE__, __FUNCTION__, \
+ #predicate); \
+ } \
+ } while (0)
__END_DECLS
diff --git a/linker/linker_block_allocator.cpp b/linker/linker_block_allocator.cpp
index 1e2f9a2..5b68b1d 100644
--- a/linker/linker_block_allocator.cpp
+++ b/linker/linker_block_allocator.cpp
@@ -27,12 +27,15 @@
*/
#include "linker_block_allocator.h"
+
#include <inttypes.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <unistd.h>
+#include "linker_debug.h"
+
static constexpr size_t kAllocateSize = PAGE_SIZE * 100;
static_assert(kAllocateSize % PAGE_SIZE == 0, "Invalid kAllocateSize.");
@@ -88,16 +91,10 @@
}
LinkerBlockAllocatorPage* page = find_page(block);
-
- if (page == nullptr) {
- abort();
- }
+ CHECK(page != nullptr);
ssize_t offset = reinterpret_cast<uint8_t*>(block) - page->bytes;
-
- if (offset % block_size_ != 0) {
- abort();
- }
+ CHECK((offset % block_size_) == 0);
memset(block, 0, block_size_);
@@ -114,7 +111,7 @@
void LinkerBlockAllocator::protect_all(int prot) {
for (LinkerBlockAllocatorPage* page = page_list_; page != nullptr; page = page->next) {
if (mprotect(page, kAllocateSize, prot) == -1) {
- abort();
+ async_safe_fatal("mprotect(%p, %zu, %d) failed: %m", page, kAllocateSize, prot);
}
}
}
@@ -125,10 +122,7 @@
LinkerBlockAllocatorPage* page = reinterpret_cast<LinkerBlockAllocatorPage*>(
mmap(nullptr, kAllocateSize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0));
-
- if (page == MAP_FAILED) {
- abort(); // oom
- }
+ CHECK(page != MAP_FAILED);
prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, page, kAllocateSize, "linker_alloc");
@@ -143,9 +137,7 @@
}
LinkerBlockAllocatorPage* LinkerBlockAllocator::find_page(void* block) {
- if (block == nullptr) {
- abort();
- }
+ CHECK(block != nullptr);
LinkerBlockAllocatorPage* page = page_list_;
while (page != nullptr) {
@@ -157,7 +149,7 @@
page = page->next;
}
- abort();
+ async_safe_fatal("couldn't find page for %p", block);
}
void LinkerBlockAllocator::purge() {