Gdb otherwise gets confused, as it considers the syscall frame to be inner to the caller frame, stopping the stack unwinding early.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/ntdll/unix/thread.c | 4 ++-- dlls/ntdll/unix/virtual.c | 18 ++++++++++-------- 2 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index e88a935ca31..9ccf03ceeb7 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -1180,7 +1180,7 @@ NTSTATUS init_thread_stack( TEB *teb, ULONG_PTR zero_bits, SIZE_T reserve_size, teb->Tib.StackBase = teb->TlsSlots[WOW64_TLS_CPURESERVED] = cpu; teb->Tib.StackLimit = stack.StackLimit; teb->DeallocationStack = stack.DeallocationStack; - thread_data->kernel_stack = stack.StackBase; + thread_data->kernel_stack = (char *)stack.DeallocationStack - kernel_stack_size; return STATUS_SUCCESS; #else /* 64-bit stack */ @@ -1201,7 +1201,7 @@ NTSTATUS init_thread_stack( TEB *teb, ULONG_PTR zero_bits, SIZE_T reserve_size, teb->Tib.StackBase = stack.StackBase; teb->Tib.StackLimit = stack.StackLimit; teb->DeallocationStack = stack.DeallocationStack; - thread_data->kernel_stack = stack.StackBase; + thread_data->kernel_stack = (char *)stack.DeallocationStack - kernel_stack_size; return STATUS_SUCCESS; }
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index 984af2d4a21..eb878171093 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -3135,13 +3135,6 @@ NTSTATUS virtual_alloc_thread_stack( INITIAL_TEB *stack, ULONG_PTR zero_bits, SI VALGRIND_STACK_REGISTER( view->base, (char *)view->base + view->size ); #endif
- /* setup no access guard page */ - set_page_vprot( view->base, page_size, VPROT_COMMITTED ); - set_page_vprot( (char *)view->base + page_size, page_size, - VPROT_READ | VPROT_WRITE | VPROT_COMMITTED | VPROT_GUARD ); - mprotect_range( view->base, 2 * page_size, 0, 0 ); - VIRTUAL_DEBUG_DUMP_VIEW( view ); - if (extra_size) { struct file_view *extra_view; @@ -3149,16 +3142,25 @@ NTSTATUS virtual_alloc_thread_stack( INITIAL_TEB *stack, ULONG_PTR zero_bits, SI /* shrink the first view and create a second one for the extra size */ /* this allows the app to free the stack without freeing the thread start portion */ view->size -= extra_size; - status = create_view( &extra_view, (char *)view->base + view->size, extra_size, + view->base = (char *)view->base + extra_size; + status = create_view( &extra_view, (char *)view->base - extra_size, extra_size, VPROT_READ | VPROT_WRITE | VPROT_COMMITTED ); if (status != STATUS_SUCCESS) { view->size += extra_size; + view->base = (char *)view->base - extra_size; delete_view( view ); goto done; } }
+ /* setup no access guard page */ + set_page_vprot( view->base, page_size, VPROT_COMMITTED ); + set_page_vprot( (char *)view->base + page_size, page_size, + VPROT_READ | VPROT_WRITE | VPROT_COMMITTED | VPROT_GUARD ); + mprotect_range( view->base, 2 * page_size, 0, 0 ); + VIRTUAL_DEBUG_DUMP_VIEW( view ); + /* note: limit is lower than base since the stack grows down */ stack->OldStackBase = 0; stack->OldStackLimit = 0;