Improve stack overflow diagnostics (take 2).
This reverts commitseb1b07469fandd14dc3b87f, and fixes the bug where we were calling mmap (which might cause errno to be set) before __set_tls (which is required to implement errno). Bug: 8557703 Change-Id: I2c36d00240c56e156e1bb430d8c22a73a068b70c
This commit is contained in:
@@ -69,9 +69,22 @@ void __init_tls(pthread_internal_t* thread) {
|
||||
thread->tls[TLS_SLOT_STACK_GUARD] = (void*) __stack_chk_guard;
|
||||
|
||||
__set_tls(thread->tls);
|
||||
|
||||
// Create and set an alternate signal stack.
|
||||
// This must happen after __set_tls, in case a system call fails and tries to set errno.
|
||||
stack_t ss;
|
||||
ss.ss_sp = mmap(NULL, SIGSTKSZ, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
|
||||
if (ss.ss_sp != MAP_FAILED) {
|
||||
ss.ss_size = SIGSTKSZ;
|
||||
ss.ss_flags = 0;
|
||||
sigaltstack(&ss, NULL);
|
||||
thread->alternate_signal_stack = ss.ss_sp;
|
||||
}
|
||||
}
|
||||
|
||||
// This trampoline is called from the assembly _pthread_clone() function.
|
||||
// This trampoline is called from the assembly _pthread_clone function.
|
||||
// Our 'tls' and __pthread_clone's 'child_stack' are one and the same, just growing in
|
||||
// opposite directions.
|
||||
extern "C" void __thread_entry(void* (*func)(void*), void* arg, void** tls) {
|
||||
// Wait for our creating thread to release us. This lets it have time to
|
||||
// notify gdb about this thread before we start doing anything.
|
||||
@@ -187,8 +200,12 @@ int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr,
|
||||
thread->attr.flags |= PTHREAD_ATTR_FLAG_USER_STACK;
|
||||
}
|
||||
|
||||
// Make room for TLS.
|
||||
// Make room for the TLS area.
|
||||
// The child stack is the same address, just growing in the opposite direction.
|
||||
// At offsets >= 0, we have the TLS slots.
|
||||
// At offsets < 0, we have the child stack.
|
||||
void** tls = (void**)((uint8_t*)(thread->attr.stack_base) + thread->attr.stack_size - BIONIC_TLS_SLOTS * sizeof(void*));
|
||||
void* child_stack = tls;
|
||||
|
||||
// Create a mutex for the thread in TLS_SLOT_SELF to wait on once it starts so we can keep
|
||||
// it from doing anything until after we notify the debugger about it
|
||||
@@ -204,7 +221,7 @@ int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr,
|
||||
|
||||
int flags = CLONE_FILES | CLONE_FS | CLONE_VM | CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM;
|
||||
|
||||
int tid = __pthread_clone(start_routine, tls, flags, arg);
|
||||
int tid = __pthread_clone(start_routine, child_stack, flags, arg);
|
||||
if (tid < 0) {
|
||||
int clone_errno = errno;
|
||||
if ((thread->attr.flags & PTHREAD_ATTR_FLAG_USER_STACK) == 0) {
|
||||
|
||||
Reference in New Issue
Block a user