Name stack+tls VMAs with PR_SET_VMA_ANON_NAME
Bionic creates a single thread mapping to hold a thread's stack and static TLS memory. Use PR_SET_VMA_ANON_NAME to name this region "stack_and_tls:tid". dumpsys meminfo can report this region as "Stack" memory. The main thread's memory is instead named stack_and_tls:main, and the VMA is renamed to stack_and_tls:main in a post-fork child. For the main thread, and threads using pthread_attr_setstack, Bionic still creates the stack_and_tls mapping, but it only has TLS memory in it. Bug: http://b/134795155 Test: run "dumpsys meminfo" and verify that this CL increases the reported stack memory usage from about 4MB to 21MB. Change-Id: Id1f39ff083329e83426130b4ef94222ffacb90ae Merged-In: Id1f39ff083329e83426130b4ef94222ffacb90ae
This commit is contained in:
parent
9cf76012aa
commit
03cef383ba
|
@ -135,8 +135,11 @@ extern "C" void __libc_init_main_thread_final() {
|
|||
|
||||
main_thread.mmap_base = mapping.mmap_base;
|
||||
main_thread.mmap_size = mapping.mmap_size;
|
||||
main_thread.mmap_base_unguarded = mapping.mmap_base_unguarded;
|
||||
main_thread.mmap_size_unguarded = mapping.mmap_size_unguarded;
|
||||
|
||||
__set_tls(&new_tcb->tls_slot(0));
|
||||
|
||||
__set_stack_and_tls_vma_name(true);
|
||||
__free_temp_bionic_tls(temp_tls);
|
||||
}
|
||||
|
|
|
@ -55,6 +55,10 @@ int fork() {
|
|||
// fork, close all of their fds blindly, and then exec.
|
||||
android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_DISABLED);
|
||||
|
||||
// Reset the stack_and_tls VMA name so it doesn't end with a tid from the
|
||||
// parent process.
|
||||
__set_stack_and_tls_vma_name(true);
|
||||
|
||||
__bionic_atfork_run_child();
|
||||
} else {
|
||||
__bionic_atfork_run_parent();
|
||||
|
|
|
@ -254,6 +254,8 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si
|
|||
ThreadMapping result = {};
|
||||
result.mmap_base = space;
|
||||
result.mmap_size = mmap_size;
|
||||
result.mmap_base_unguarded = space + stack_guard_size;
|
||||
result.mmap_size_unguarded = mmap_size - stack_guard_size - PTHREAD_GUARD_SIZE;
|
||||
result.static_tls = space + mmap_size - PTHREAD_GUARD_SIZE - layout.size();
|
||||
result.stack_base = space;
|
||||
result.stack_top = result.static_tls;
|
||||
|
@ -315,12 +317,33 @@ static int __allocate_thread(pthread_attr_t* attr, bionic_tcb** tcbp, void** chi
|
|||
thread->attr = *attr;
|
||||
thread->mmap_base = mapping.mmap_base;
|
||||
thread->mmap_size = mapping.mmap_size;
|
||||
thread->mmap_base_unguarded = mapping.mmap_base_unguarded;
|
||||
thread->mmap_size_unguarded = mapping.mmap_size_unguarded;
|
||||
|
||||
*tcbp = tcb;
|
||||
*child_stack = stack_top;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __set_stack_and_tls_vma_name(bool is_main_thread) {
|
||||
// Name the thread's stack-and-tls area to help with debugging. This mapped area also includes
|
||||
// static TLS data, which is typically a few pages (e.g. bionic_tls).
|
||||
pthread_internal_t* thread = __get_thread();
|
||||
const char* name;
|
||||
if (is_main_thread) {
|
||||
name = "stack_and_tls:main";
|
||||
} else {
|
||||
// The kernel doesn't copy the name string, but this variable will last at least as long as the
|
||||
// mapped area. The mapped area's VMAs are unmapped with a single call to munmap.
|
||||
auto& name_buffer = thread->vma_name_buffer;
|
||||
static_assert(arraysize(name_buffer) >= arraysize("stack_and_tls:") + 11 + 1);
|
||||
async_safe_format_buffer(name_buffer, arraysize(name_buffer), "stack_and_tls:%d", thread->tid);
|
||||
name = name_buffer;
|
||||
}
|
||||
prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, thread->mmap_base_unguarded, thread->mmap_size_unguarded,
|
||||
name);
|
||||
}
|
||||
|
||||
__attribute__((no_sanitize("hwaddress")))
|
||||
static int __pthread_start(void* arg) {
|
||||
pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(arg);
|
||||
|
@ -333,6 +356,7 @@ static int __pthread_start(void* arg) {
|
|||
// accesses previously made by the creating thread are visible to us.
|
||||
thread->startup_handshake_lock.lock();
|
||||
|
||||
__set_stack_and_tls_vma_name(false);
|
||||
__init_additional_stacks(thread);
|
||||
|
||||
void* result = thread->start_routine(thread->start_routine_arg);
|
||||
|
|
|
@ -129,6 +129,11 @@ class pthread_internal_t {
|
|||
void* mmap_base;
|
||||
size_t mmap_size;
|
||||
|
||||
// The location of the VMA to label as the thread's stack_and_tls.
|
||||
void* mmap_base_unguarded;
|
||||
size_t mmap_size_unguarded;
|
||||
char vma_name_buffer[32];
|
||||
|
||||
thread_local_dtor* thread_local_dtors;
|
||||
|
||||
/*
|
||||
|
@ -147,6 +152,8 @@ class pthread_internal_t {
|
|||
struct ThreadMapping {
|
||||
char* mmap_base;
|
||||
size_t mmap_size;
|
||||
char* mmap_base_unguarded;
|
||||
size_t mmap_size_unguarded;
|
||||
|
||||
char* static_tls;
|
||||
char* stack_base;
|
||||
|
@ -162,6 +169,7 @@ __LIBC_HIDDEN__ void __free_temp_bionic_tls(bionic_tls* tls);
|
|||
__LIBC_HIDDEN__ void __init_additional_stacks(pthread_internal_t*);
|
||||
__LIBC_HIDDEN__ int __init_thread(pthread_internal_t* thread);
|
||||
__LIBC_HIDDEN__ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_size);
|
||||
__LIBC_HIDDEN__ void __set_stack_and_tls_vma_name(bool is_main_thread);
|
||||
|
||||
__LIBC_HIDDEN__ pthread_t __pthread_internal_add(pthread_internal_t* thread);
|
||||
__LIBC_HIDDEN__ pthread_internal_t* __pthread_internal_find(pthread_t pthread_id, const char* caller);
|
||||
|
|
Loading…
Reference in New Issue