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.
FILE* fp = fopen("/proc/self/maps", "re");
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];
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;
void* allocation = mmap(nullptr, allocation_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
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");
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) {
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");
}

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))
#endif
static inline void
_getentropy_fail(void)
{
async_safe_fatal("getentropy failed");
static inline void _getentropy_fail(void) {
async_safe_fatal("getentropy failed: %s", strerror(errno));
}
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,
uint32_t rtld_flags) {
if (strlen(name) >= PATH_MAX) {
DL_ERR("library name \"%s\" too long", name);
return nullptr;
async_safe_fatal("library name \"%s\" too long", name);
}
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() {
static_assert(sizeof(page_info) % 16 == 0,
"sizeof(page_info) is not multiple of 16");
void* map_ptr = mmap(nullptr, PAGE_SIZE,
PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
static_assert(sizeof(page_info) % 16 == 0, "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);
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");
@ -246,11 +244,11 @@ void LinkerMemoryAllocator::initialize_allocators() {
void* LinkerMemoryAllocator::alloc_mmap(size_t size) {
size_t allocated_size = PAGE_END(size + sizeof(page_info));
void* map_ptr = mmap(nullptr, allocated_size,
PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
void* map_ptr = mmap(nullptr, allocated_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,
-1, 0);
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");

View File

@ -88,12 +88,12 @@ class linker_vector_allocator {
T* allocate(size_t n, const T* hint = nullptr) {
size_t size = n * sizeof(T);
void* ptr = mmap(const_cast<T*>(hint), size,
PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
void* ptr = mmap(const_cast<T*>(hint), size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,
-1, 0);
if (ptr == MAP_FAILED) {
// 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.
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");

View File

@ -117,7 +117,7 @@ void LinkerBlockAllocator::create_new_page() {
"Invalid sizeof(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) {
abort(); // oom

View File

@ -276,11 +276,8 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args) {
const char* executable_path = get_executable_path();
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();
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) {
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...
__builtin___clear_cache(base, base + (PAGE_SIZE * 2));
}