Always log errno when aborting.

(Where errno is relevant.)

Also consistently use -1 as the fd for anonymous mmaps. (It doesn't matter,
but it's more common, and potentially more intention-revealing.)

Bug: http://b/65608572
Test: ran tests
Change-Id: Ie9a207632d8242f42086ba3ca862519014c3c102
This commit is contained in:
Elliott Hughes 2017-09-15 16:09:22 -07:00
parent 3b64f8ecb3
commit 7b0af7ad82
9 changed files with 18 additions and 26 deletions

View File

@ -164,7 +164,7 @@ static int __pthread_attr_getstack_main_thread(void** stack_base, size_t* stack_
// Hunt for the region that contains that address. // Hunt for the region that contains that address.
FILE* fp = fopen("/proc/self/maps", "re"); FILE* fp = fopen("/proc/self/maps", "re");
if (fp == nullptr) { if (fp == nullptr) {
async_safe_fatal("couldn't open /proc/self/maps"); async_safe_fatal("couldn't open /proc/self/maps: %s", strerror(errno));
} }
char line[BUFSIZ]; char line[BUFSIZ];
while (fgets(line, sizeof(line), fp) != NULL) { while (fgets(line, sizeof(line), fp) != NULL) {

View File

@ -59,13 +59,13 @@ void __init_tls(pthread_internal_t* thread) {
size_t allocation_size = BIONIC_TLS_SIZE + 2 * PAGE_SIZE; size_t allocation_size = BIONIC_TLS_SIZE + 2 * PAGE_SIZE;
void* allocation = mmap(nullptr, allocation_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); void* allocation = mmap(nullptr, allocation_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (allocation == MAP_FAILED) { if (allocation == MAP_FAILED) {
async_safe_fatal("failed to allocate TLS"); async_safe_fatal("failed to allocate TLS: %s", strerror(errno));
} }
prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, allocation, allocation_size, "bionic TLS guard page"); prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, allocation, allocation_size, "bionic TLS guard page");
thread->bionic_tls = reinterpret_cast<bionic_tls*>(static_cast<char*>(allocation) + PAGE_SIZE); thread->bionic_tls = reinterpret_cast<bionic_tls*>(static_cast<char*>(allocation) + PAGE_SIZE);
if (mprotect(thread->bionic_tls, BIONIC_TLS_SIZE, PROT_READ | PROT_WRITE) != 0) { if (mprotect(thread->bionic_tls, BIONIC_TLS_SIZE, PROT_READ | PROT_WRITE) != 0) {
async_safe_fatal("failed to mprotect TLS"); async_safe_fatal("failed to mprotect TLS: %s", strerror(errno));
} }
prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, thread->bionic_tls, BIONIC_TLS_SIZE, "bionic TLS"); prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, thread->bionic_tls, BIONIC_TLS_SIZE, "bionic TLS");
} }

View File

@ -45,10 +45,8 @@ extern int __register_atfork(void (*)(void), void(*)(void), void (*)(void), void
#define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f)) #define _ARC4_ATFORK(f) pthread_atfork(NULL, NULL, (f))
#endif #endif
static inline void static inline void _getentropy_fail(void) {
_getentropy_fail(void) async_safe_fatal("getentropy failed: %s", strerror(errno));
{
async_safe_fatal("getentropy failed");
} }
volatile sig_atomic_t _rs_forked; volatile sig_atomic_t _rs_forked;

View File

@ -286,8 +286,7 @@ soinfo* soinfo_alloc(android_namespace_t* ns, const char* name,
struct stat* file_stat, off64_t file_offset, struct stat* file_stat, off64_t file_offset,
uint32_t rtld_flags) { uint32_t rtld_flags) {
if (strlen(name) >= PATH_MAX) { if (strlen(name) >= PATH_MAX) {
DL_ERR("library name \"%s\" too long", name); async_safe_fatal("library name \"%s\" too long", name);
return nullptr;
} }
TRACE("name %s: allocating soinfo for ns=%p", name, ns); TRACE("name %s: allocating soinfo for ns=%p", name, ns);

View File

@ -200,12 +200,10 @@ void LinkerSmallObjectAllocator::create_page_record(void* page_addr, size_t free
} }
void LinkerSmallObjectAllocator::alloc_page() { void LinkerSmallObjectAllocator::alloc_page() {
static_assert(sizeof(page_info) % 16 == 0, static_assert(sizeof(page_info) % 16 == 0, "sizeof(page_info) is not multiple of 16");
"sizeof(page_info) is not multiple of 16"); void* map_ptr = mmap(nullptr, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
void* map_ptr = mmap(nullptr, PAGE_SIZE,
PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
if (map_ptr == MAP_FAILED) { if (map_ptr == MAP_FAILED) {
async_safe_fatal("mmap failed"); async_safe_fatal("mmap failed: %s", strerror(errno));
} }
prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, map_ptr, PAGE_SIZE, "linker_alloc_small_objects"); prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, map_ptr, PAGE_SIZE, "linker_alloc_small_objects");
@ -246,11 +244,11 @@ void LinkerMemoryAllocator::initialize_allocators() {
void* LinkerMemoryAllocator::alloc_mmap(size_t size) { void* LinkerMemoryAllocator::alloc_mmap(size_t size) {
size_t allocated_size = PAGE_END(size + sizeof(page_info)); size_t allocated_size = PAGE_END(size + sizeof(page_info));
void* map_ptr = mmap(nullptr, allocated_size, void* map_ptr = mmap(nullptr, allocated_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,
PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); -1, 0);
if (map_ptr == MAP_FAILED) { if (map_ptr == MAP_FAILED) {
async_safe_fatal("mmap failed"); async_safe_fatal("mmap failed: %s", strerror(errno));
} }
prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, map_ptr, allocated_size, "linker_alloc_lob"); prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, map_ptr, allocated_size, "linker_alloc_lob");

View File

@ -88,12 +88,12 @@ class linker_vector_allocator {
T* allocate(size_t n, const T* hint = nullptr) { T* allocate(size_t n, const T* hint = nullptr) {
size_t size = n * sizeof(T); size_t size = n * sizeof(T);
void* ptr = mmap(const_cast<T*>(hint), size, void* ptr = mmap(const_cast<T*>(hint), size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,
PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); -1, 0);
if (ptr == MAP_FAILED) { if (ptr == MAP_FAILED) {
// Spec says we need to throw std::bad_alloc here but because our // Spec says we need to throw std::bad_alloc here but because our
// code does not support exception handling anyways - we are going to abort. // code does not support exception handling anyways - we are going to abort.
async_safe_fatal("mmap failed"); async_safe_fatal("mmap failed: %s", strerror(errno));
} }
prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, ptr, size, "linker_alloc_vector"); prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, ptr, size, "linker_alloc_vector");

View File

@ -117,7 +117,7 @@ void LinkerBlockAllocator::create_new_page() {
"Invalid sizeof(LinkerBlockAllocatorPage)"); "Invalid sizeof(LinkerBlockAllocatorPage)");
LinkerBlockAllocatorPage* page = reinterpret_cast<LinkerBlockAllocatorPage*>( LinkerBlockAllocatorPage* page = reinterpret_cast<LinkerBlockAllocatorPage*>(
mmap(nullptr, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0)); mmap(nullptr, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0));
if (page == MAP_FAILED) { if (page == MAP_FAILED) {
abort(); // oom abort(); // oom

View File

@ -276,11 +276,8 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args) {
const char* executable_path = get_executable_path(); const char* executable_path = get_executable_path();
soinfo* si = soinfo_alloc(&g_default_namespace, executable_path, &file_stat, 0, RTLD_GLOBAL); soinfo* si = soinfo_alloc(&g_default_namespace, executable_path, &file_stat, 0, RTLD_GLOBAL);
if (si == nullptr) {
async_safe_fatal("Couldn't allocate soinfo: out of memory?");
}
/* bootstrap the link map, the main exe always needs to be first */ // Bootstrap the link map, the main exe always needs to be first.
si->set_main_executable(); si->set_main_executable();
link_map* map = &(si->link_map_head); link_map* map = &(si->link_map_head);

View File

@ -235,7 +235,7 @@ TEST(sys_mman, mremap_PTRDIFF_MAX) {
TEST(sys_mman, mmap_bug_27265969) { TEST(sys_mman, mmap_bug_27265969) {
char* base = reinterpret_cast<char*>(mmap(nullptr, PAGE_SIZE * 2, PROT_EXEC | PROT_READ, char* base = reinterpret_cast<char*>(mmap(nullptr, PAGE_SIZE * 2, PROT_EXEC | PROT_READ,
MAP_ANONYMOUS | MAP_PRIVATE, 0, 0)); MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
// Some kernels had bugs that would cause segfaults here... // Some kernels had bugs that would cause segfaults here...
__builtin___clear_cache(base, base + (PAGE_SIZE * 2)); __builtin___clear_cache(base, base + (PAGE_SIZE * 2));
} }