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.
https://gitlab.winehq.org/wine/wine/-/merge_requests/1088
Goes atop !436. The last three commits belong to this MR.
--
v6: vkd3d-shader/spirv: Introduce orderedness to comparison instructions.
vkd3d-shader/dxil: Implement the DXIL CMP2 instruction.
vkd3d-shader/spirv: Support bool dst register in spirv_compiler_emit_comparison_instruction().
https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/441
Goes atop !436. The last three commits belong to this MR.
--
v5: vkd3d-shader/dxil: Implement the DXIL CMP2 instruction.
vkd3d-shader/spirv: Support orderedness inversion in comparison instructions.
vkd3d-shader/spirv: Support bool result in spirv_compiler_emit_comparison_instruction().
vkd3d-shader/dxil: Implement the DXIL CAST instruction.
https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/441
This fixes the following issue:
- Thread X holds the typelib cache list CS, and is iterating through the list.
- Thread Y calls Release on the typelib interface, reference count hits 0, it's waiting for the cache list CS to remove this typelib.
- Thread X finds the typelib in the cache list, returns it, exits the CS.
- Thread Y enters now the CS, removes the typelib from the cache list, and proceeds to free all of the resources associated with the typelib.
- Thread X tries to use the typelib, use after free.
The method used here to prevent incrementing the reference count is borrowed from MR !2752.
An alternative could be to decouple the actual typelib data from the `ITypeLib2` interface itself, e.g what gets stored into the typelib cache is just the data for the typelib, which would have its own private reference count locked behind the cache list CS. When the public `ITypeLib2` interface's reference count hits 0, it'd lock the typelib cache list CS, decrement the private reference count, and if the private reference count is 0 remove it from the list.
The alternative method would require major restructuring of the code, which is why I'd prefer to use the one in this MR.
--
v3: oleaut32: Lock ITypeLib2 interface reference count behind the typelib cache critical section on Release.
https://gitlab.winehq.org/wine/wine/-/merge_requests/4002
This fixes the following issue:
- Thread X holds the typelib cache list CS, and is iterating through the list.
- Thread Y calls Release on the typelib interface, reference count hits 0, it's waiting for the cache list CS to remove this typelib.
- Thread X finds the typelib in the cache list, returns it, exits the CS.
- Thread Y enters now the CS, removes the typelib from the cache list, and proceeds to free all of the resources associated with the typelib.
- Thread X tries to use the typelib, use after free.
The method used here to prevent incrementing the reference count is borrowed from MR !2752.
An alternative could be to decouple the actual typelib data from the `ITypeLib2` interface itself, e.g what gets stored into the typelib cache is just the data for the typelib, which would have its own private reference count locked behind the cache list CS. When the public `ITypeLib2` interface's reference count hits 0, it'd lock the typelib cache list CS, decrement the private reference count, and if the private reference count is 0 remove it from the list.
The alternative method would require major restructuring of the code, which is why I'd prefer to use the one in this MR.
--
v2: oleaut32: Lock ITypeLib2 interface reference count behind the typelib cache critical section.
https://gitlab.winehq.org/wine/wine/-/merge_requests/4002
--
v4: dmloader: Mark cached objects as loaded.
dmsynth: Don't leak modulators.
dmsynth: Free the allocated presets manually.
dmsynth: Remove useless private data checks.
dmsynth: Create one FluidSynth sample per wave.
dmsynth: Use generators to set root key and fine tune.
dmsynth: Keep track of voice/wave mapping.
https://gitlab.winehq.org/wine/wine/-/merge_requests/4339