Using a dedicated exit jmpbuf and removing the need for assembly routines.
When Wine handles an exception in unix code, we return to user mode by jumping to the last syscall frame. This can leave some pthread cancel cleanups registered, in the pthread internal linked list, and at the same time later overwrite the stack frame they were registered for.
In the same way, jumping to the exit frame on thread exit or abort, can also leave some cleanup handlers registered for invalid stack frames.
Depending on the implementation, calling pthread_exit will cause all the registered pthread cleanup handlers to be called, possibly jumping back to now overwritten stack frames and causing segmentation faults.
Exiting a pthread normally, by returning from its procedure, or calling exit(0) for the main thread doesn't run pthread_exit and doesn't call cleanup handlers, avoiding that situation.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52213
### Additional note:
For robustness, we should probably try to execute these cleanup handlers when unwinding the stack frames, as we would otherwise leave pthread objects in a potential problematic state (like a mutex locked, etc).
It is however hard to do so when the handlers are registered from some C code: pthread C implementation is done by calling some internal pthread functions to register the handlers, and they aren't registered as standard unwind handlers.
Only pthread_cancel and pthread_exit can unwind and call / unregister the C handlers, but interrupting that procedure, for instance calling setjmp / longjmp from withing our own handler isn't supported.
From C++ code, pthread cleanup handlers are registered through C++ class constructors / destructors, and it would then be possible to partially unwind and call them at the same time.
-- v11: ntdll: Unwind i386 syscall stack frames on thread abort. ntdll: Add a syscall_cfa member to the i386 syscall frame. ntdll: Unwind x86_64 syscall stack frames on thread abort. ntdll: Add a syscall_cfa member to the x86_64 syscall frame. ntdll: Add comments to stack switches in dispatchers.
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52213 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54346 --- dlls/ntdll/unix/signal_arm.c | 7 +++++++ dlls/ntdll/unix/signal_arm64.c | 6 ++++++ dlls/ntdll/unix/signal_i386.c | 7 +++++++ dlls/ntdll/unix/signal_x86_64.c | 6 ++++++ 4 files changed, 26 insertions(+)
diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c index 28cb2222809..ea062f0520c 100644 --- a/dlls/ntdll/unix/signal_arm.c +++ b/dlls/ntdll/unix/signal_arm.c @@ -1173,6 +1173,7 @@ __ASM_GLOBAL_FUNC( call_user_mode_callback, "str sp, [r4, #0x1d8]\n\t" /* arm_thread_data()->syscall_frame */ "ldr r6, [r5, #0x50]\n\t" /* prev_frame->syscall_table */ "str r6, [sp, #0x50]\n\t" /* frame->syscall_table */ + /* switch to user stack */ "mov sp, r1\n\t" "bx ip" )
@@ -1618,6 +1619,7 @@ __ASM_GLOBAL_FUNC( signal_start_thread, "cbnz r6, 1f\n\t" "sub r6, sp, #0x160\n\t" /* sizeof(struct syscall_frame) */ "str r6, [r3, #0x1d8]\n\t" /* arm_thread_data()->syscall_frame */ + /* switch to kernel stack */ "1:\tmov sp, r6\n\t" "bl " __ASM_NAME("call_init_thunk") )
@@ -1660,6 +1662,7 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "vstm r0, {d0-d15}\n\t" #endif "mov r6, sp\n\t" + /* switch to kernel stack */ "mov sp, r1\n\t" "mov r8, r1\n\t" "ldr r5, [r1, #0x50]\n\t" /* frame->syscall_table */ @@ -1700,9 +1703,11 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "it ne\n\t" "ldmne r8, {r0-r3}\n\t" "ldr lr, [r8, #0x3c]\n\t" + /* switch to user stack */ "ldr sp, [r8, #0x38]\n\t" "add r8, r8, #0x10\n\t" "ldm r8, {r4-r12,pc}\n" + "5:\tmovw r0, #0x000d\n\t" /* STATUS_INVALID_PARAMETER */ "movt r0, #0xc000\n\t" "add sp, sp, #0x10\n\t" @@ -1737,12 +1742,14 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher, "vstm r4, {d0-d15}\n\t" #endif "ldr ip, [r0, r2, lsl #2]\n\t" + /* switch to kernel stack */ "mov sp, r1\n\t" "mov r0, r3\n\t" /* args */ "blx ip\n" "mov r8, sp\n\t" "ldr r1, [r8, #0x44]\n\t" /* frame->restore_flags */ "cbnz r1, 1f\n\t" + /* switch to user stack */ "ldr sp, [r8, #0x38]\n\t" "add r8, r8, #0x10\n\t" "ldm r8, {r4-r12,pc}\n\t" diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c index 4897b8e1824..db5e86a3f5f 100644 --- a/dlls/ntdll/unix/signal_arm64.c +++ b/dlls/ntdll/unix/signal_arm64.c @@ -1133,6 +1133,7 @@ __ASM_GLOBAL_FUNC( call_user_mode_callback, "sub x3, sp, #0x330\n\t" /* sizeof(struct syscall_frame) */ "str x3, [x18, #0x2f8]\n\t" /* arm64_thread_data()->syscall_frame */ "ldr x8, [x7, #0x118]\n\t" /* prev_frame->syscall_table */ + /* switch to user stack */ "mov sp, x1\n\t" /* stack */ "stp x7, x8, [x3, #0x110]\n\t" /* frame->prev_frame, frame->syscall_table */ "br x5" ) @@ -1682,6 +1683,7 @@ __ASM_GLOBAL_FUNC( signal_start_thread, "cbnz x8, 1f\n\t" "sub x8, sp, #0x330\n\t" /* sizeof(struct syscall_frame) */ "str x8, [x3, #0x2f8]\n\t" /* arm64_thread_data()->syscall_frame */ + /* switch to kernel stack */ "1:\tmov sp, x8\n\t" "bl " __ASM_NAME("call_init_thunk") )
@@ -1733,6 +1735,7 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "stp q26, q27, [x10, #0x2d0]\n\t" "stp q28, q29, [x10, #0x2f0]\n\t" "stp q30, q31, [x10, #0x310]\n\t" + /* switch to kernel stack */ "mov sp, x10\n\t" "and x20, x8, #0xfff\n\t" /* syscall number */ "ubfx x21, x8, #12, #2\n\t" /* syscall table number */ @@ -1804,6 +1807,7 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "1:\tldp x16, x17, [sp, #0x100]\n\t" "msr NZCV, x17\n\t" "ldp x30, x17, [sp, #0xf0]\n\t" + /* switch to user stack */ "mov sp, x17\n\t" "ret x16\n" "4:\tmov x0, #0xc0000000\n\t" /* STATUS_INVALID_PARAMETER */ @@ -1835,6 +1839,7 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher, "stp x30, x9, [x10, #0xf0]\n\t" "mrs x9, NZCV\n\t" "stp x30, x9, [x10, #0x100]\n\t" + /* switch to kernel stack */ "mov sp, x10\n\t" "ldr x16, [x0, x1, lsl 3]\n\t" "mov x0, x2\n\t" /* args */ @@ -1843,6 +1848,7 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher, "cbnz w16, " __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") "\n\t" "ldr x18, [sp, #0x90]\n\t" "ldp x16, x17, [sp, #0xf8]\n\t" + /* switch to user stack */ "mov sp, x16\n\t" "ret x17" )
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 293b8689c06..9485ffe6a85 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -1602,6 +1602,7 @@ __ASM_GLOBAL_FUNC( call_user_mode_callback, "movl %esp,0x1f8(%edx)\n\t" /* x86_thread_data()->syscall_frame */ "movl 0x1c(%ebp),%ecx\n\t" /* func */ "movl 0x0c(%ebp),%edx\n\t" /* args */ + /* switch to user stack */ "leal -4(%edx),%esp\n\t" "pushl 0x10(%ebp)\n\t" /* len */ "pushl %edx\n\t" /* args */ @@ -2491,6 +2492,7 @@ __ASM_GLOBAL_FUNC( signal_start_thread, "leal -0x380(%esp),%eax\n\t" /* sizeof(struct syscall_frame) */ "andl $~63,%eax\n\t" "movl %eax,0x1f8(%ecx)\n" /* x86_thread_data()->syscall_frame */ + /* switch to kernel stack */ "1:\tmovl %eax,%esp\n\t" "pushl %ecx\n\t" /* teb */ "pushl 16(%ebp)\n\t" /* suspend */ @@ -2604,6 +2606,7 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "jmp 4f\n" "3:\tfnsave 0x40(%ecx)\n\t" "fwait\n" + /* switch to kernel stack */ "4:\tmovl %ecx,%esp\n\t" "movl 0x1c(%esp),%edx\n\t" /* frame->eax */ "andl $0xfff,%edx\n\t" /* syscall number */ @@ -2660,6 +2663,7 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, __ASM_CFI(".cfi_same_value %ebx\n\t") "movl 0x08(%esp),%ecx\n\t" /* frame->eip */ __ASM_CFI(".cfi_register %eip, %ecx\n\t") + /* switch to user stack */ "movl 0x0c(%esp),%esp\n\t" /* frame->esp */ __ASM_CFI(".cfi_same_value %esp\n\t") "pushl %ecx\n\t" @@ -2674,6 +2678,7 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "1:\tmovl 0x0c(%esp),%ebx\n\t" /* frame->esp */ __ASM_CFI(".cfi_register %esp, %ebx\n\t") "movw 0x12(%esp),%ss\n\t" + /* switch to user stack */ "xchgl %ebx,%esp\n\t" __ASM_CFI(".cfi_def_cfa %esp, 0\n\t") __ASM_CFI(".cfi_same_value %esp\n\t") @@ -2749,6 +2754,7 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher, "movl %edx,-16(%ecx)\n\t" "movl (%esp),%eax\n\t" /* handle */ "movl 8(%esp),%edx\n\t" /* code */ + /* switch to kernel stack */ "leal -16(%ecx),%esp\n\t" "call *(%eax,%edx,4)\n\t" "leal 16(%esp),%esp\n\t" @@ -2763,6 +2769,7 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher, "jnz " __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") "\n\t" "movl 0x08(%esp),%ecx\n\t" /* frame->eip */ __ASM_CFI(".cfi_register %eip, %ecx\n\t") + /* switch to user stack */ "movl 0x0c(%esp),%esp\n\t" /* frame->esp */ __ASM_CFI(".cfi_same_value %esp\n\t") "pushl %ecx\n\t" diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index eac5d961a07..525fbd03a57 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -1593,6 +1593,7 @@ __ASM_GLOBAL_FUNC( call_user_mode_callback, "movq %rdi,%rcx\n\t" /* id */ "movq %rdx,%r8\n\t" /* len */ "movq %rsi,%rdx\n\t" /* args */ + /* switch to user stack */ "leaq -0x20(%rsi),%rsp\n\t" "push $0\n\t" "jmpq *%r9" ) @@ -2544,6 +2545,7 @@ __ASM_GLOBAL_FUNC( signal_start_thread, "leaq -0x400(%rsp),%rax\n\t" /* sizeof(struct syscall_frame) */ "andq $~63,%rax\n\t" "movq %rax,0x328(%rcx)\n" /* amd64_thread_data()->syscall_frame */ + /* switch to kernel stack */ "1:\tmovq %rax,%rsp\n\t" "call " __ASM_NAME("call_init_thunk"))
@@ -2668,6 +2670,7 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "movq 0x28(%rsp),%r12\n\t" /* 5th argument */ "movq 0x30(%rsp),%r13\n\t" /* 6th argument */ "leaq 0x38(%rsp),%rsi\n\t" /* 7th argument */ + /* switch to kernel stack */ "movq %rcx,%rsp\n\t" "movq 0x00(%rcx),%rax\n\t" "movq 0x18(%rcx),%r11\n\t" /* 2nd argument */ @@ -2753,6 +2756,7 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "movq 0x80(%rcx),%r11\n\t" /* frame->eflags */ "pushq %r11\n\t" "popfq\n\t" + /* switch to user stack */ "movq 0x88(%rcx),%rsp\n\t" __ASM_CFI(".cfi_def_cfa rsp, 0\n\t") __ASM_CFI(".cfi_same_value rsp\n\t") @@ -2870,6 +2874,7 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher, "mov %r9,%rcx\n\t" "2:\n\t" #endif + /* switch to kernel stack */ "movq %rcx,%rsp\n" "movq %r8,%rdi\n\t" /* args */ "callq *(%r10,%rdx,8)\n\t" @@ -2897,6 +2902,7 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher, "movq 0x28(%rcx),%rdi\n\t" __ASM_CFI(".cfi_same_value rdi\n\t") "movq 0x20(%rcx),%rsi\n\t" + /* switch to user stack */ __ASM_CFI(".cfi_same_value rsi\n\t") "movq 0x88(%rcx),%rsp\n\t" __ASM_CFI(".cfi_def_cfa rsp, 0\n\t")
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52213 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54346 --- dlls/ntdll/unix/signal_x86_64.c | 44 +++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 18 deletions(-)
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 525fbd03a57..1e4d43fd702 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -403,7 +403,7 @@ struct syscall_frame SYSTEM_SERVICE_TABLE *syscall_table; /* 00a8 */ DWORD syscall_flags; /* 00b0 */ DWORD restore_flags; /* 00b4 */ - DWORD align[2]; /* 00b8 */ + ULONG64 syscall_cfa; /* 00b8 */ XMM_SAVE_AREA32 xsave; /* 00c0 */ DECLSPEC_ALIGN(64) XSTATE xstate; /* 02c0 */ }; @@ -1572,9 +1572,10 @@ __ASM_GLOBAL_FUNC( call_user_mode_callback, "movq %rcx,-0x38(%rbp)\n\t" /* ret_ptr */ "movq %r8,-0x40(%rbp)\n\t" /* ret_len */ "mov 0x10(%rbp),%r11\n\t" /* teb */ - "subq $0x410,%rsp\n\t" /* sizeof(struct syscall_frame) + ebp + exception */ + "subq $0x408,%rsp\n\t" /* sizeof(struct syscall_frame) + exception */ "andq $~63,%rsp\n\t" - "movq %rbp,0x400(%rsp)\n\t" + "leaq 0x10(%rbp),%rax\n\t" + "movq %rax,0xb8(%rsp)\n\t" /* frame->syscall_cfa */ "movq 0x328(%r11),%r10\n\t" /* amd64_thread_data()->syscall_frame */ "movq (%r11),%rax\n\t" /* NtCurrentTeb()->Tib.ExceptionList */ "movq %rax,0x408(%rsp)\n\t" @@ -1608,7 +1609,8 @@ __ASM_GLOBAL_FUNC( user_mode_callback_return, "movq 0x328(%rcx),%r10\n\t" /* amd64_thread_data()->syscall_frame */ "movq 0xa0(%r10),%r11\n\t" /* frame->prev_frame */ "movq %r11,0x328(%rcx)\n\t" /* amd64_thread_data()->syscall_frame = prev_frame */ - "movq 0x400(%r10),%rbp\n\t" /* call_user_mode_callback rbp */ + "movq 0xb8(%r10),%rbp\n\t" /* frame->syscall_cfa */ + "subq $0x10,%rbp\n\t" __ASM_CFI(".cfi_def_cfa_register %rbp\n\t") __ASM_CFI(".cfi_rel_offset %rbx,-0x08\n\t") __ASM_CFI(".cfi_rel_offset %r12,-0x10\n\t") @@ -2439,6 +2441,7 @@ void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, B { struct amd64_thread_data *thread_data = (struct amd64_thread_data *)&teb->GdiTebBatch; struct syscall_frame *frame = thread_data->syscall_frame; + ULONG64 syscall_cfa = frame->syscall_cfa; CONTEXT *ctx, context = { 0 }; I386_CONTEXT *wow_context;
@@ -2512,6 +2515,7 @@ void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, B frame->restore_flags |= CONTEXT_INTEGER; frame->syscall_flags = syscall_flags; frame->syscall_table = KeServiceDescriptorTable; + frame->syscall_cfa = syscall_cfa;
pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL ); __wine_syscall_dispatcher_return( frame, 0 ); @@ -2522,20 +2526,22 @@ void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, B * signal_start_thread */ __ASM_GLOBAL_FUNC( signal_start_thread, - "subq $56,%rsp\n\t" - __ASM_CFI(".cfi_adjust_cfa_offset 56\n\t") - "movq %rbp,48(%rsp)\n\t" - __ASM_CFI(".cfi_rel_offset %rbp,48\n\t") - "movq %rbx,40(%rsp)\n\t" - __ASM_CFI(".cfi_rel_offset %rbx,40\n\t") - "movq %r12,32(%rsp)\n\t" - __ASM_CFI(".cfi_rel_offset %r12,32\n\t") - "movq %r13,24(%rsp)\n\t" - __ASM_CFI(".cfi_rel_offset %r13,24\n\t") - "movq %r14,16(%rsp)\n\t" - __ASM_CFI(".cfi_rel_offset %r14,16\n\t") - "movq %r15,8(%rsp)\n\t" - __ASM_CFI(".cfi_rel_offset %r15,8\n\t") + "subq $0x38,%rsp\n\t" + __ASM_CFI(".cfi_adjust_cfa_offset 0x38\n\t") + "movq %rbp,0x30(%rsp)\n\t" + __ASM_CFI(".cfi_rel_offset %rbp,0x30\n\t") + "leaq 0x30(%rsp),%rbp\n\t" + __ASM_CFI(".cfi_def_cfa_register %rbp\n\t") + "movq %rbx,-0x08(%rbp)\n\t" + __ASM_CFI(".cfi_rel_offset %rbx,-0x08\n\t") + "movq %r12,-0x10(%rbp)\n\t" + __ASM_CFI(".cfi_rel_offset %r12,-0x10\n\t") + "movq %r13,-0x18(%rbp)\n\t" + __ASM_CFI(".cfi_rel_offset %r13,-0x18\n\t") + "movq %r14,-0x20(%rbp)\n\t" + __ASM_CFI(".cfi_rel_offset %r14,-0x20\n\t") + "movq %r15,-0x28(%rbp)\n\t" + __ASM_CFI(".cfi_rel_offset %r15,-0x28\n\t") /* store exit frame */ "movq %rsp,0x320(%rcx)\n\t" /* amd64_thread_data()->exit_frame */ /* set syscall frame */ @@ -2547,6 +2553,8 @@ __ASM_GLOBAL_FUNC( signal_start_thread, "movq %rax,0x328(%rcx)\n" /* amd64_thread_data()->syscall_frame */ /* switch to kernel stack */ "1:\tmovq %rax,%rsp\n\t" + "leaq 0x10(%rbp),%rax\n\t" + "movq %rax,0xb8(%rsp)\n\t" /* frame->syscall_cfa */ "call " __ASM_NAME("call_init_thunk"))
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52213 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54346 --- dlls/ntdll/unix/signal_x86_64.c | 103 ++++++++++++++++++++------------ dlls/ntdll/unix/thread.c | 7 ++- 2 files changed, 72 insertions(+), 38 deletions(-)
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 1e4d43fd702..41bf1da8f68 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -1650,13 +1650,15 @@ NTSTATUS KeUserModeCallback( ULONG id, const void *args, ULONG len, void **ret_p { struct syscall_frame *frame = amd64_thread_data()->syscall_frame; void *args_data = (void *)((frame->rsp - len) & ~15); + NTSTATUS status;
if ((char *)ntdll_get_thread_data()->kernel_stack + min_kernel_stack > (char *)&frame) return STATUS_STACK_OVERFLOW;
memcpy( args_data, args, len ); - return call_user_mode_callback( id, args_data, len, ret_ptr, ret_len, - pKiUserCallbackDispatcher, NtCurrentTeb() ); + status = call_user_mode_callback( id, args_data, len, ret_ptr, ret_len, pKiUserCallbackDispatcher, NtCurrentTeb() ); + if (status == STATUS_THREAD_IS_TERMINATING) abort_thread( 0 ); + return status; }
@@ -2100,10 +2102,17 @@ static void abrt_handler( int signal, siginfo_t *siginfo, void *sigcontext ) * * Handler for SIGQUIT. */ -static void quit_handler( int signal, siginfo_t *siginfo, void *ucontext ) +static void quit_handler( int signal, siginfo_t *siginfo, void *sigcontext ) { + ucontext_t *ucontext = sigcontext; + struct syscall_frame *frame; + init_handler( ucontext ); - abort_thread(0); + + if (!is_inside_syscall( ucontext ) && (frame = amd64_thread_data()->syscall_frame)) + NtCallbackReturn( NULL, 0, STATUS_THREAD_IS_TERMINATING ); + + abort_thread( 0 ); }
@@ -2647,8 +2656,6 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "1:\txsave64 0xc0(%rcx)\n\t" "jmp 3f\n" "2:\tfxsave64 0xc0(%rcx)\n" - /* remember state when $rcx is pointing to "frame" */ - __ASM_CFI(".cfi_remember_state\n\t") "3:\tleaq 0x98(%rcx),%rbp\n\t" __ASM_CFI_CFA_IS_AT1(rbp, 0x70) __ASM_CFI_REG_IS_AT1(rsp, rbp, 0x70) @@ -2680,6 +2687,18 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "leaq 0x38(%rsp),%rsi\n\t" /* 7th argument */ /* switch to kernel stack */ "movq %rcx,%rsp\n\t" + /* we're now on the kernel stack, stitch unwind info with previous frame */ + __ASM_CFI_CFA_IS_AT1(rbp, 0x20) /* frame->syscall_cfa */ + __ASM_CFI_REG_IS_AT1(rsp, rbp, 0x20) + __ASM_CFI(".cfi_rel_offset %rip,-0x08\n\t") + __ASM_CFI(".cfi_rel_offset %rbp,-0x10\n\t") + __ASM_CFI(".cfi_rel_offset %rbx,-0x18\n\t") + __ASM_CFI(".cfi_rel_offset %r12,-0x20\n\t") + __ASM_CFI(".cfi_rel_offset %r13,-0x28\n\t") + __ASM_CFI(".cfi_rel_offset %r14,-0x30\n\t") + __ASM_CFI(".cfi_rel_offset %r15,-0x38\n\t") + __ASM_CFI(".cfi_undefined %rdi\n\t") + __ASM_CFI(".cfi_undefined %rsi\n\t") "movq 0x00(%rcx),%rax\n\t" "movq 0x18(%rcx),%r11\n\t" /* 2nd argument */ "movl %eax,%ebx\n\t" @@ -2709,8 +2728,6 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "movq (%rbx),%r10\n\t" /* table->ServiceTable */ "callq *(%r10,%rax,8)\n\t" "leaq -0x98(%rbp),%rcx\n\t" - /* $rcx is now pointing to "frame" again */ - __ASM_CFI(".cfi_restore_state\n") __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") ":\n\t" "movl 0xb4(%rcx),%edx\n\t" /* frame->restore_flags */ #ifdef __linux__ @@ -2764,30 +2781,36 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "movq 0x80(%rcx),%r11\n\t" /* frame->eflags */ "pushq %r11\n\t" "popfq\n\t" + + /* push kernel stack cfi */ + __ASM_CFI("\t.cfi_remember_state\n") /* switch to user stack */ "movq 0x88(%rcx),%rsp\n\t" - __ASM_CFI(".cfi_def_cfa rsp, 0\n\t") - __ASM_CFI(".cfi_same_value rsp\n\t") + __ASM_CFI(".cfi_def_cfa %rsp, 0\n\t") + __ASM_CFI(".cfi_same_value %rsp\n\t") + __ASM_CFI_REG_IS_AT2(rip, rcx, 0x70, 0x00) + __ASM_CFI(".cfi_undefined %rbp\n\t") + __ASM_CFI(".cfi_undefined %rbx\n\t") + __ASM_CFI(".cfi_undefined %r12\n\t") + __ASM_CFI(".cfi_undefined %r13\n\t") + __ASM_CFI(".cfi_same_value r14\n\t") + __ASM_CFI(".cfi_undefined %r15\n\t") + __ASM_CFI(".cfi_same_value rdi\n\t") + __ASM_CFI(".cfi_same_value rsi\n\t") "movq 0x70(%rcx),%rcx\n\t" /* frame->rip */ __ASM_CFI(".cfi_register rip, rcx\n\t") "pushq %rcx\n\t" __ASM_CFI(".cfi_adjust_cfa_offset 8\n\t") "ret\n\t" - /* $rcx is now pointing to "frame" again */ - __ASM_CFI(".cfi_restore_state\n\t") - /* remember state when $rcx is pointing to "frame" */ - __ASM_CFI(".cfi_remember_state\n\t") + /* pop kernel stack cfi */ + __ASM_CFI("\t.cfi_restore_state\n") + "1:\tleaq 0x70(%rcx),%rsp\n\t" - __ASM_CFI_CFA_IS_AT1(rsp, 0x18) - __ASM_CFI_REG_IS_AT1(rsp, rsp, 0x18) - __ASM_CFI_REG_IS_AT1(rip, rsp, 0x00) "testl $0x2,%edx\n\t" /* CONTEXT_INTEGER */ "jnz 1f\n\t" "movq 0x10(%rsp),%r11\n\t" /* frame->eflags */ "movq (%rsp),%rcx\n\t" /* frame->rip */ - __ASM_CFI(".cfi_register rip, rcx\n\t") "iretq\n" - __ASM_CFI_REG_IS_AT1(rip, rsp, 0x00) "1:\tmovq 0x00(%rcx),%rax\n\t" "movq 0x18(%rcx),%rdx\n\t" "movq 0x30(%rcx),%r8\n\t" @@ -2796,21 +2819,8 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "movq 0x48(%rcx),%r11\n\t" "movq 0x10(%rcx),%rcx\n" "iretq\n" - __ASM_CFI_CFA_IS_AT1(rbp, 0x70) - __ASM_CFI_REG_IS_AT1(rsp, rbp, 0x70) - __ASM_CFI_REG_IS_AT1(rip, rbp, 0x58) - __ASM_CFI_REG_IS_AT2(rbx, rbp, 0xf0, 0x7e) - __ASM_CFI_REG_IS_AT2(rsi, rbp, 0x88, 0x7f) - __ASM_CFI_REG_IS_AT2(rdi, rbp, 0x90, 0x7f) - __ASM_CFI_REG_IS_AT2(r12, rbp, 0xb8, 0x7f) - __ASM_CFI_REG_IS_AT1(r13, rbp, 0x40) - __ASM_CFI_REG_IS_AT1(r14, rbp, 0x48) - __ASM_CFI_REG_IS_AT1(r15, rbp, 0x50) - __ASM_CFI_REG_IS_AT1(rbp, rbp, 0x00) "5:\tmovl $0xc000000d,%eax\n\t" /* STATUS_INVALID_PARAMETER */ "movq %rsp,%rcx\n\t" - /* $rcx is now pointing to "frame" again */ - __ASM_CFI(".cfi_restore_state\n\t") "jmp " __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") "\n\t" ".globl " __ASM_NAME("__wine_syscall_dispatcher_return") "\n" __ASM_NAME("__wine_syscall_dispatcher_return") ":\n\t" @@ -2884,9 +2894,22 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher, #endif /* switch to kernel stack */ "movq %rcx,%rsp\n" + /* we're now on the kernel stack, stitch unwind info with previous frame */ + __ASM_CFI_CFA_IS_AT2(rsp, 0xb8, 0x01) /* frame->syscall_cfa */ + __ASM_CFI_REG_IS_AT2(rsp, rsp, 0xb8, 0x01) + __ASM_CFI(".cfi_rel_offset %rip,-0x08\n\t") + __ASM_CFI(".cfi_rel_offset %rbp,-0x10\n\t") + __ASM_CFI(".cfi_rel_offset %rbx,-0x18\n\t") + __ASM_CFI(".cfi_rel_offset %r12,-0x20\n\t") + __ASM_CFI(".cfi_rel_offset %r13,-0x28\n\t") + __ASM_CFI(".cfi_rel_offset %r14,-0x30\n\t") + __ASM_CFI(".cfi_rel_offset %r15,-0x38\n\t") + __ASM_CFI(".cfi_undefined %rdi\n\t") + __ASM_CFI(".cfi_undefined %rsi\n\t") "movq %r8,%rdi\n\t" /* args */ "callq *(%r10,%rdx,8)\n\t" "movq %rsp,%rcx\n" + "movq 0x98(%rcx),%rbp\n\t" "movdqa 0x1c0(%rcx),%xmm6\n\t" "movdqa 0x1d0(%rcx),%xmm7\n\t" "movdqa 0x1e0(%rcx),%xmm8\n\t" @@ -2906,15 +2929,21 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher, "1:\n\t" #endif "movq 0x60(%rcx),%r14\n\t" - __ASM_CFI(".cfi_same_value r14\n\t") "movq 0x28(%rcx),%rdi\n\t" - __ASM_CFI(".cfi_same_value rdi\n\t") "movq 0x20(%rcx),%rsi\n\t" /* switch to user stack */ - __ASM_CFI(".cfi_same_value rsi\n\t") "movq 0x88(%rcx),%rsp\n\t" - __ASM_CFI(".cfi_def_cfa rsp, 0\n\t") - __ASM_CFI(".cfi_same_value rsp\n\t") + __ASM_CFI(".cfi_def_cfa %rsp, 0\n\t") + __ASM_CFI(".cfi_same_value %rsp\n\t") + __ASM_CFI_REG_IS_AT2(rip, rcx, 0x70, 0x00) + __ASM_CFI(".cfi_undefined %rbp\n\t") + __ASM_CFI(".cfi_undefined %rbx\n\t") + __ASM_CFI(".cfi_undefined %r12\n\t") + __ASM_CFI(".cfi_undefined %r13\n\t") + __ASM_CFI(".cfi_same_value r14\n\t") + __ASM_CFI(".cfi_undefined %r15\n\t") + __ASM_CFI(".cfi_same_value rdi\n\t") + __ASM_CFI(".cfi_same_value rsi\n\t") "pushq 0x70(%rcx)\n\t" /* frame->rip */ __ASM_CFI(".cfi_adjust_cfa_offset 8\n\t") "ret" ) diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index 2a9bc41e788..04cdcba41ed 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -1078,7 +1078,7 @@ static void contexts_from_server( CONTEXT *context, context_t server_contexts[2] /*********************************************************************** * pthread_exit_wrapper */ -static void pthread_exit_wrapper( int status ) +static DECLSPEC_NORETURN void pthread_exit_wrapper( int status ) { close( ntdll_get_thread_data()->wait_fd[0] ); close( ntdll_get_thread_data()->wait_fd[1] ); @@ -1404,7 +1404,12 @@ void abort_thread( int status ) { pthread_sigmask( SIG_BLOCK, &server_block_set, NULL ); if (InterlockedDecrement( &nb_threads ) <= 0) abort_process( status ); + +#if defined(__x86_64__) + pthread_exit_wrapper( status ); +#else signal_exit_thread( status, pthread_exit_wrapper, NtCurrentTeb() ); +#endif }
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52213 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54346 --- dlls/ntdll/unix/signal_i386.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 9485ffe6a85..d62d966f7aa 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -466,9 +466,10 @@ struct syscall_frame * 32-bit mode, but some processors fault if they're not in writable memory. */ DECLSPEC_ALIGN(64) XSTATE xstate; /* 240 */ + UINT syscall_cfa; /* 380 */ };
-C_ASSERT( sizeof(struct syscall_frame) == 0x380 ); +C_ASSERT( sizeof(struct syscall_frame) == 0x3c0 );
struct x86_thread_data { @@ -1590,9 +1591,10 @@ __ASM_GLOBAL_FUNC( call_user_mode_callback, __ASM_CFI(".cfi_rel_offset %edi,-12\n\t") "movl 0x20(%ebp),%edx\n\t" /* teb */ "pushl 0(%edx)\n\t" /* teb->Tib.ExceptionList */ - "subl $0x384,%esp\n\t" /* sizeof(struct syscall_frame) + ebp */ + "subl $0x3c0,%esp\n\t" /* sizeof(struct syscall_frame) */ "andl $~63,%esp\n\t" - "movl %ebp,0x380(%esp)\n\t" + "leal 8(%ebp),%eax\n\t" + "movl %eax,0x380(%esp)\n\t" /* frame->syscall_cfa */ "movl 0x1f8(%edx),%ecx\n\t" /* x86_thread_data()->syscall_frame */ "movl (%ecx),%eax\n\t" /* frame->syscall_flags */ "movl %eax,(%esp)\n\t" @@ -1622,7 +1624,8 @@ __ASM_GLOBAL_FUNC( user_mode_callback_return, "movl 0x1f8(%edx),%eax\n\t" /* x86_thread_data()->syscall_frame */ "movl 0x3c(%eax),%ecx\n\t" /* frame->prev_frame */ "movl %ecx,0x1f8(%edx)\n\t" /* x86_thread_data()->syscall_frame */ - "movl 0x380(%eax),%ebp\n\t" /* call_user_mode_callback ebp */ + "movl 0x380(%eax),%ebp\n\t" /* frame->syscall_cfa */ + "subl $8,%ebp\n\t" __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") __ASM_CFI(".cfi_rel_offset %ebp,0\n\t") __ASM_CFI(".cfi_def_cfa_register %ebp\n\t") @@ -2420,6 +2423,7 @@ void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, B struct x86_thread_data *thread_data = (struct x86_thread_data *)&teb->GdiTebBatch; struct syscall_frame *frame = thread_data->syscall_frame; CONTEXT *ctx, context = { CONTEXT_ALL }; + UINT syscall_cfa = frame->syscall_cfa; DWORD *stack;
ldt_set_fs( thread_data->fs, teb ); @@ -2461,6 +2465,7 @@ void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, B frame->syscall_flags = syscall_flags; frame->syscall_table = KeServiceDescriptorTable; frame->restore_flags |= LOWORD(CONTEXT_INTEGER); + frame->syscall_cfa = syscall_cfa;
pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL ); __wine_syscall_dispatcher_return( frame, 0 ); @@ -2489,11 +2494,13 @@ __ASM_GLOBAL_FUNC( signal_start_thread, "movl 0x1f8(%ecx),%eax\n\t" /* x86_thread_data()->syscall_frame */ "orl %eax,%eax\n\t" "jnz 1f\n\t" - "leal -0x380(%esp),%eax\n\t" /* sizeof(struct syscall_frame) */ + "leal -0x3c0(%esp),%eax\n\t" /* sizeof(struct syscall_frame) */ "andl $~63,%eax\n\t" "movl %eax,0x1f8(%ecx)\n" /* x86_thread_data()->syscall_frame */ /* switch to kernel stack */ "1:\tmovl %eax,%esp\n\t" + "leal 8(%ebp),%eax\n\t" + "movl %eax,0x380(%esp)\n\t" /* frame->syscall_cfa */ "pushl %ecx\n\t" /* teb */ "pushl 16(%ebp)\n\t" /* suspend */ "pushl 12(%ebp)\n\t" /* arg */
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52213 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54346 --- dlls/ntdll/unix/signal_i386.c | 92 ++++++++++++++++++++--------------- dlls/ntdll/unix/thread.c | 2 +- 2 files changed, 55 insertions(+), 39 deletions(-)
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index d62d966f7aa..01dc618f065 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -1660,13 +1660,16 @@ NTSTATUS KeUserModeCallback( ULONG id, const void *args, ULONG len, void **ret_p { struct syscall_frame *frame = x86_thread_data()->syscall_frame; void *args_data = (void *)((frame->esp - len) & ~15); + NTSTATUS status;
if ((char *)ntdll_get_thread_data()->kernel_stack + min_kernel_stack > (char *)&frame) return STATUS_STACK_OVERFLOW;
memcpy( args_data, args, len ); - return call_user_mode_callback( id, args_data, len, ret_ptr, ret_len, - pKiUserCallbackDispatcher, NtCurrentTeb() ); + status = call_user_mode_callback( id, args_data, len, ret_ptr, ret_len, + pKiUserCallbackDispatcher, NtCurrentTeb() ); + if (status == STATUS_THREAD_IS_TERMINATING) abort_thread( 0 ); + return status; }
@@ -2061,8 +2064,14 @@ static void abrt_handler( int signal, siginfo_t *siginfo, void *sigcontext ) */ static void quit_handler( int signal, siginfo_t *siginfo, void *sigcontext ) { + struct syscall_frame *frame; + init_handler( sigcontext ); - abort_thread(0); + + if (!is_inside_syscall( sigcontext ) && (frame = x86_thread_data()->syscall_frame)) + NtCallbackReturn( NULL, 0, STATUS_THREAD_IS_TERMINATING ); + + abort_thread( 0 ); }
@@ -2615,6 +2624,14 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "fwait\n" /* switch to kernel stack */ "4:\tmovl %ecx,%esp\n\t" + /* we're now on the kernel stack, stitch unwind info with previous frame */ + __ASM_CFI_CFA_IS_AT2(ebp, 0xcc, 0x06) /* frame->syscall_cfa */ + __ASM_CFI_REG_IS_AT2(esp, ebp, 0xcc, 0x06) + __ASM_CFI(".cfi_offset %eip,-4\n\t") + __ASM_CFI(".cfi_offset %ebp,-8\n\t") + __ASM_CFI(".cfi_offset %ebx,-12\n\t") + __ASM_CFI(".cfi_offset %esi,-16\n\t") + __ASM_CFI(".cfi_offset %edi,-20\n\t") "movl 0x1c(%esp),%edx\n\t" /* frame->eax */ "andl $0xfff,%edx\n\t" /* syscall number */ "cmpl 8(%ebx),%edx\n\t" /* table->ServiceLimit */ @@ -2632,13 +2649,6 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "leal -0x34(%ebp),%esp\n"
__ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") ":\t" - __ASM_CFI_CFA_IS_AT1(esp, 0x0c) - __ASM_CFI_REG_IS_AT1(esp, esp, 0x0c) - __ASM_CFI_REG_IS_AT1(eip, esp, 0x08) - __ASM_CFI_REG_IS_AT1(ebx, esp, 0x20) - __ASM_CFI_REG_IS_AT1(edi, esp, 0x2c) - __ASM_CFI_REG_IS_AT1(esi, esp, 0x30) - __ASM_CFI_REG_IS_AT1(ebp, esp, 0x34) "movl 0(%esp),%ecx\n\t" /* frame->syscall_flags + (frame->restore_flags << 16) */ "testl $0x68 << 16,%ecx\n\t" /* CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS | CONTEXT_XSAVE */ "jz 3f\n\t" @@ -2657,40 +2667,47 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "2:\tfrstor 0x40(%esp)\n\t" "fwait\n" "3:\tmovl 0x2c(%esp),%edi\n\t" - __ASM_CFI(".cfi_remember_state\n\t") - __ASM_CFI(".cfi_same_value %edi\n\t") "movl 0x30(%esp),%esi\n\t" - __ASM_CFI(".cfi_same_value %esi\n\t") "movl 0x34(%esp),%ebp\n\t" - __ASM_CFI(".cfi_same_value %ebp\n\t") "testl $0x7 << 16,%ecx\n\t" /* CONTEXT_CONTROL | CONTEXT_SEGMENTS | CONTEXT_INTEGER */ "jnz 1f\n\t" "movl 0x20(%esp),%ebx\n\t" - __ASM_CFI(".cfi_remember_state\n\t") - __ASM_CFI(".cfi_same_value %ebx\n\t") "movl 0x08(%esp),%ecx\n\t" /* frame->eip */ - __ASM_CFI(".cfi_register %eip, %ecx\n\t") + /* push kernel stack cfi */ + __ASM_CFI("\t.cfi_remember_state\n") /* switch to user stack */ "movl 0x0c(%esp),%esp\n\t" /* frame->esp */ + __ASM_CFI(".cfi_def_cfa %esp,0\n\t") __ASM_CFI(".cfi_same_value %esp\n\t") + __ASM_CFI(".cfi_register %eip, %ecx\n\t") + __ASM_CFI(".cfi_undefined %ebp\n\t") + __ASM_CFI(".cfi_undefined %ebx\n\t") + __ASM_CFI(".cfi_undefined %esi\n\t") + __ASM_CFI(".cfi_undefined %edi\n\t") "pushl %ecx\n\t" __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") "ret\n" + /* pop kernel stack cfi */ __ASM_CFI("\t.cfi_restore_state\n") + "1:\ttestl $0x2 << 16,%ecx\n\t" /* CONTEXT_INTEGER */ "jz 1f\n\t" "movl 0x1c(%esp),%eax\n\t" "movl 0x24(%esp),%ecx\n\t" "movl 0x28(%esp),%edx\n" "1:\tmovl 0x0c(%esp),%ebx\n\t" /* frame->esp */ - __ASM_CFI(".cfi_register %esp, %ebx\n\t") "movw 0x12(%esp),%ss\n\t" + /* push kernel stack cfi */ + __ASM_CFI("\t.cfi_remember_state\n") /* switch to user stack */ "xchgl %ebx,%esp\n\t" - __ASM_CFI(".cfi_def_cfa %esp, 0\n\t") + __ASM_CFI(".cfi_def_cfa %esp,0\n\t") __ASM_CFI(".cfi_same_value %esp\n\t") - __ASM_CFI_REG_IS_AT1(eip, ebx, 0x08) - __ASM_CFI_REG_IS_AT1(ebx, ebx, 0x20) + __ASM_CFI(".cfi_register %eip, %ecx\n\t") + __ASM_CFI(".cfi_undefined %ebp\n\t") + __ASM_CFI(".cfi_undefined %ebx\n\t") + __ASM_CFI(".cfi_undefined %esi\n\t") + __ASM_CFI(".cfi_undefined %edi\n\t") "pushl 0x04(%ebx)\n\t" /* frame->eflags */ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") "pushl 0x10(%ebx)\n\t" /* frame->cs */ @@ -2708,23 +2725,16 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "popl %ds\n\t" __ASM_CFI(".cfi_adjust_cfa_offset -4\n\t") "iret\n" + /* pop kernel stack cfi */ __ASM_CFI("\t.cfi_restore_state\n") + "6:\tmovl $0xc000000d,%eax\n\t" /* STATUS_INVALID_PARAMETER */ "jmp " __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") "\n\t"
".globl " __ASM_NAME("__wine_syscall_dispatcher_return") "\n" __ASM_NAME("__wine_syscall_dispatcher_return") ":\n\t" - __ASM_CFI(".cfi_remember_state\n\t") - __ASM_CFI(".cfi_def_cfa %esp, 4\n\t") - __ASM_CFI(".cfi_restore %esp\n\t") - __ASM_CFI(".cfi_restore %eip\n\t") - __ASM_CFI(".cfi_restore %ebx\n\t") - __ASM_CFI(".cfi_restore %edi\n\t") - __ASM_CFI(".cfi_restore %esi\n\t") - __ASM_CFI(".cfi_restore %ebp\n\t") "movl 8(%esp),%eax\n\t" "movl 4(%esp),%esp\n\t" - __ASM_CFI(".cfi_restore_state\n\t") "jmp " __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") )
@@ -2763,22 +2773,28 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher, "movl 8(%esp),%edx\n\t" /* code */ /* switch to kernel stack */ "leal -16(%ecx),%esp\n\t" + /* we're now on the kernel stack, stitch unwind info with previous frame */ + __ASM_CFI_CFA_IS_AT2(esp, 0x90, 0x07) /* frame->syscall_cfa */ + __ASM_CFI_REG_IS_AT2(esp, esp, 0x90, 0x07) + __ASM_CFI(".cfi_offset %eip,-4\n\t") + __ASM_CFI(".cfi_offset %ebp,-8\n\t") + __ASM_CFI(".cfi_offset %ebx,-12\n\t") + __ASM_CFI(".cfi_offset %esi,-16\n\t") + __ASM_CFI(".cfi_offset %edi,-20\n\t") "call *(%eax,%edx,4)\n\t" "leal 16(%esp),%esp\n\t" - __ASM_CFI_CFA_IS_AT1(esp, 0x0c) - __ASM_CFI_REG_IS_AT1(esp, esp, 0x0c) - __ASM_CFI_REG_IS_AT1(eip, esp, 0x08) - __ASM_CFI_REG_IS_AT1(ebx, esp, 0x20) - __ASM_CFI_REG_IS_AT1(edi, esp, 0x2c) - __ASM_CFI_REG_IS_AT1(esi, esp, 0x30) - __ASM_CFI_REG_IS_AT1(ebp, esp, 0x34) "testw $0xffff,2(%esp)\n\t" /* frame->restore_flags */ "jnz " __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") "\n\t" "movl 0x08(%esp),%ecx\n\t" /* frame->eip */ - __ASM_CFI(".cfi_register %eip, %ecx\n\t") /* switch to user stack */ "movl 0x0c(%esp),%esp\n\t" /* frame->esp */ + __ASM_CFI(".cfi_def_cfa %esp,0\n\t") __ASM_CFI(".cfi_same_value %esp\n\t") + __ASM_CFI(".cfi_register %eip, %ecx\n\t") + __ASM_CFI(".cfi_undefined %ebp\n\t") + __ASM_CFI(".cfi_undefined %ebx\n\t") + __ASM_CFI(".cfi_undefined %esi\n\t") + __ASM_CFI(".cfi_undefined %edi\n\t") "pushl %ecx\n\t" __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") "ret" ) diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index 04cdcba41ed..195dbfca470 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -1405,7 +1405,7 @@ void abort_thread( int status ) pthread_sigmask( SIG_BLOCK, &server_block_set, NULL ); if (InterlockedDecrement( &nb_threads ) <= 0) abort_process( status );
-#if defined(__x86_64__) +#if defined(__x86_64__) || defined(__i386__) pthread_exit_wrapper( status ); #else signal_exit_thread( status, pthread_exit_wrapper, NtCurrentTeb() );
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=139715
Your paranoid android.
=== debian11b (64 bit WoW report) ===
quartz: dsoundrender: Timeout
Updated to a new version that stitches kernel frames together. It breaks backtraces in Gdb sadly. I also only did x86 because I have no idea what ARM uses and it didn't have any CFI.