This is to avoid a crash in UnregisterDeviceNotification when
called a second time for the same handle.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58050
<details>
<summary>ASan Details</summary>
```
=================================================================
==control.exe==536==ERROR: AddressSanitizer: heap-use-after-free on address 0x7f07e3ae0568 at pc 0x6ffffdc6f092 bp 0x7ffffe1fdae0 sp 0x7ffffe1fdb28
READ of size 8 at 0x7f07e3ae0568 thread T0
#0 0x6ffffdc6f091 in list_remove ...\wine\include\wine\list.h:100
#1 0x6ffffdc6efcc in I_ScUnregisterDeviceNotification ...\wine\dlls\sechost\service.c:2193
#2 0x6ffffa5a16e2 in UnregisterDeviceNotification ...\wine\dlls\user32\input.c:594
#3 0x6ffffdbe3a5f in test_di_dialoHWND__ ...\wine\dlls\joy.cpl\dinput.c:809
#4 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
#5 0x6ffffa5c3b6e in call_dialog_proc ...\wine\dlls\user32\winproc.c:130
#6 0x6ffffa5c3c6e in WINPROC_CallDlgProcW ...\wine\dlls\user32\winproc.c:951
#7 0x6ffffa58f8cc in USER_DefDlgProcW ...\wine\dlls\user32\defdlg.c:375
#8 0x6ffffa58f864 in USER_DefDlgProc ...\wine\dlls\user32\defdlg.c:420
#9 0x6ffffb4a39d5 in UXTHEME_DefDlgProc ...\wine\dlls\uxtheme\dialog.c:192
#10 0x6ffffa58fb8d in DialogWndProcW ...\wine\dlls\user32\defdlg.c:438
#11 0x6fffffdaffdf in NtdllDialogWndProc_W+0xf (C:\windows\system32\ntdll.dll+0x17003ffdf)
#12 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
#13 0x6ffffa5c2ba8 in call_window_proc ...\wine\dlls\user32\winproc.c:111
#14 0x6ffffa5c2d92 in dispatch_win_proc_params ...\wine\dlls\user32\winproc.c
#15 0x6ffffa5aee20 in dispatwin_proc_params ...\wine\dlls\user32\message.c:567
#16 0x6ffffa5aeda4 in SendMessageW ...\wine\dlls\user32\message.c:586
#17 0x6ffffde75873 in PROPSHEET_Cancel ...\wine\dlls\comctl32\propsheet.c:1949
#18 0x6ffffde75b80 in PROPSHEET_DoCommand ...\wine\dlls\comctl32\propsheet.c:3359
#19 0x6ffffde7085e in PROPSHEET_DialogProc ...\wine\dlls\comctl32\propsheet.c:3694
#20 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
#21 0x6ffffa5c3b6e in call_dialog_proc ...\wine\dlls\user32\winproc.c:130
#22 0x6ffffa5c3c6e in WINPROC_CallDlgProcW ...\wine\dlls\user32\winproc.c:951
#23 0x6ffffa58f8cc in USER_DefDlgProcW ...\wine\dlls\user32\defdlg.c:375
#24 0x6ffffa58f864 in USER_DefDlgProc ...\wine\dlls\user32\defdlg.c:420
#25 0x6ffffb4a39d5 in UXTHEME_DefDlgProc ...\wine\dlls\uxtheme\dialog.c:192
#26 0x6ffffa58fb8d in DialogWndProcW ...\wine\dlls\user32\defdlg.c:438
#27 0x6fffffdaffdf in NtdllDialogWndProc_W+0xf (C:\windows\system32\ntdll.dll+0x17003ffdf)
#28 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
#29 0x6ffffa5c2ba8 in call_window_proc ...\wine\dlls\user32\winproc.c:111
#30 0x6ffffa5c2d92 in dispatch_win_proc_params ...\wine\dlls\user32\winproc.c
#31 0x6ffffa5aee20 in dispatwin_proc_params ...\wine\dlls\user32\message.c:567
#32 0x6ffffa5aeda4 in SendMessageW ...\wine\dlls\user32\message.c:586
#33 0x6ffffdd9a2fb in BUTTON_WindowProc+0x1c7b (C:\windows\winsxs\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef\comctl32.dll+0x18000a2fb)
#34 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
#35 0x6ffffa5c2ba8 in call_window_proc ...\wine\dlls\user32\winproc.c:111
#36 0x6ffffa5c2d92 in dispatch_win_proc_params ...\wine\dlls\user32\winproc.c
#37 0x6ffffa5af7db in dispatch_message ...\wine\dlls\user32\message.c:804
#38 0x6ffffa5af881 in DispatchMessageW ...\wine\dlls\user32\message.c:890
#39 0x6ffffa591e90 in IsDialogMessageW ...\wine\dlls\user32\dialog.c:1293
#40 0x6ffffde76a93 in PROPSHEET_IsDialogMessage ...\wine\dlls\comctl32\propsheet.c:2956
#41 0x6ffffde6fd45 in do_loop ...\wine\dlls\comctl32\propsheet.c:2971
#42 0x6ffffde6c938 in PROPSHEET_PropertySheet ...\wine\dlls\comctl32\propsheet.c:3013
#43 0x6ffffde6cddd in PropertySheetW ...\wine\dlls\comctl32\propsheet.c:3124
#44 0x6ffffdbe754c in display_cpl_sheets ...\wine\dlls\joy.cpl\main.c:482
#45 0x6ffffdbe6d2f in CPlApplet ...\wine\dlls\joy.cpl\main.c:570
#46 0x6ffffb98f235 in Control_DoLaunch ...\wine\dlls\shell32\control.c:822
#47 0x6ffffb98e8e4 in Control_RunDLLW ...\wine\dlls\shell32\control.c:847
#48 0x0001400011b6 in launch+0x26 (C:\windows\system32\control.exe+0x1400011b6)
#49 0x000140001044 in STANCE__+0x44 (C:\windows\system32\control.exe+0x140001044)
#50 0x000140001320 in wmain+0xb0 (C:\windows\system32\control.exe+0x140001320)
#51 0x000140001245 in wmainCRTStartup ...\wine\dlls\msvcrt\crt_wmain.c:58
#52 0x6fffffc3565e in BaseThreadInitThunk ...\wine\dlls\kernel32\thread.c:61
#53 0x6fffffdbbb1a (C:\windows\system32\ntdll.dll+0x17004bb1a)
0x7f07e3ae0568 is located 8 bytes inside of 68-byte region [0x7f07e3ae0560,0x7f07e3ae05a4)
freed by thread T0 here:
#0 0x6ffffe84a381 in free+0x81 (C:\windows\system32\libclang_rt.asan_dynamic-x86_64.dll+0x18004a381)
#1 0x6ffffdc6eff8 in I_ScUnregisterDeviceNotification ...\wine\dlls\sechost\service.c:2196
#2 0x6ffffa5a16e2 in UnregisterDeviceNotification ...\wine\dlls\user32\input.c:594
#3 0x6ffffdbe3a5f in test_di_dialoHWND__ ...\wine\dlls\joy.cpl\dinput.c:809
#4 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
#5 0x6ffffa5c3b6e in call_dialog_proc ...\wine\dlls\user32\winproc.c:130
#6 0x6ffffa5c3c6e in WINPROC_CallDlgProcW ...\wine\dlls\user32\winproc.c:951
#7 0x6ffffa58f8cc in USER_DefDlgProcW ...\wine\dlls\user32\defdlg.c:375
#8 0x6ffffa58f864 in USER_DefDlgProc ...\wine\dlls\user32\defdlg.c:420
#9 0x6ffffb4a39d5 in UXTHEME_DefDlgProc ...\wine\dlls\uxtheme\dialog.c:192
#10 0x6ffffa58fb8d in DialogWndProcW ...\wine\dlls\user32\defdlg.c:438
#11 0x6fffffdaffdf in NtdllDialogWndProc_W+0xf (C:\windows\system32\ntdll.dll+0x17003ffdf)
#12 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
#13 0x6ffffa5c2ba8 in call_window_proc ...\wine\dlls\user32\winproc.c:111
#14 0x6ffffa5c2d92 in dispatch_win_proc_params ...\wine\dlls\user32\winproc.c
#15 0x6ffffa5aee20 in dispatwin_proc_params ...\wine\dlls\user32\message.c:567
#16 0x6ffffa5aeda4 in SendMessageW ...\wine\dlls\user32\message.c:586
#17 0x6ffffde75df3 in PROPSHEET_CanSetCurSel ...\wine\dlls\comctl32\propsheet.c:2120
#18 0x6ffffde702ef in PROPSHEET_DialogProc ...\wine\dlls\comctl32\propsheet.c:3722
#19 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
#20 0x6ffffa5c3b6e in call_dialog_proc ...\wine\dlls\user32\winproc.c:130
#21 0x6ffffa5c3c6e in WINPROC_CallDlgProcW ...\wine\dlls\user32\winproc.c:951
#22 0x6ffffa58f8cc in USER_DefDlgProcW ...\wine\dlls\user32\defdlg.c:375
#23 0x6ffffa58f864 in USER_DefDlgProc ...\wine\dlls\user32\defdlg.c:420
#24 0x6ffffb4a39d5 in UXTHEME_DefDlgProc ...\wine\dlls\uxtheme\dialog.c:192
#25 0x6ffffa58fb8d in DialogWndProcW ...\wine\dlls\user32\defdlg.c:438
#26 0x6fffffdaffdf in NtdllDialogWndProc_W+0xf (C:\windows\system32\ntdll.dll+0x17003ffdf)
#27 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
previously allocated by thread T0 here:
#0 0x6ffffe84a5b6 in calloc+0x86 (C:\windows\system32\libclang_rt.asan_dynamic-x86_64.dll+0x18004a5b6)
#1 0x6ffffdc6e50b in I_ScRegisterDeviceNotification ...\wine\dlls\sechost\service.c:2141
#2 0x6ffffa5a1377 in RegisterDeviceNotificationW ...\wine\dlls\user32\input.c
#3 0x6ffffdbe398c in test_di_dialoHWND__ ...\wine\dlls\joy.cpl\dinput.c:795
#4 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
#5 0x6ffffa5c3b6e in call_dialog_proc ...\wine\dlls\user32\winproc.c:130
#6 0x6ffffa5c3c6e in WINPROC_CallDlgProcW ...\wine\dlls\user32\winproc.c:951
#7 0x6ffffa58f8cc in USER_DefDlgProcW ...\wine\dlls\user32\defdlg.c:375
#8 0x6ffffa58f864 in USER_DefDlgProc ...\wine\dlls\user32\defdlg.c:420
#9 0x6ffffb4a39d5 in UXTHEME_DefDlgProc ...\wine\dlls\uxtheme\dialog.c:192
#10 0x6ffffa58fb8d in DialogWndProcW ...\wine\dlls\user32\defdlg.c:438
#11 0x6fffffdaffdf in NtdllDialogWndProc_W+0xf (C:\windows\system32\ntdll.dll+0x17003ffdf)
#12 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
#13 0x6ffffa5c2ba8 in call_window_proc ...\wine\dlls\user32\winproc.c:111
#14 0x6ffffa5c2d92 in dispatch_win_proc_params ...\wine\dlls\user32\winproc.c
#15 0x6ffffa5aee20 in dispatwin_proc_params ...\wine\dlls\user32\message.c:567
#16 0x6ffffa5aeda4 in SendMessageW ...\wine\dlls\user32\message.c:586
#17 0x6ffffde73e49 in PROPSHEET_SetCurSel ...\wine\dlls\comctl32\propsheet.c:2199
#18 0x6ffffde702c3 in PROPSHEET_DialogProc ...\wine\dlls\comctl32\propsheet.c:3717
#19 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
#20 0x6ffffa5c3b6e in call_dialog_proc ...\wine\dlls\user32\winproc.c:130
#21 0x6ffffa5c3c6e in WINPROC_CallDlgProcW ...\wine\dlls\user32\winproc.c:951
#22 0x6ffffa58f8cc in USER_DefDlgProcW ...\wine\dlls\user32\defdlg.c:375
#23 0x6ffffa58f864 in USER_DefDlgProc ...\wine\dlls\user32\defdlg.c:420
#24 0x6ffffb4a39d5 in UXTHEME_DefDlgProc ...\wine\dlls\uxtheme\dialog.c:192
#25 0x6ffffa58fb8d in DialogWndProcW ...\wine\dlls\user32\defdlg.c:438
#26 0x6fffffdaffdf in NtdllDialogWndProc_W+0xf (C:\windows\system32\ntdll.dll+0x17003ffdf)
#27 0x6ffffa5c3f6e in WINPROC_wrapper ...\wine\dlls\user32\winproc.c:86
SUMMARY: AddressSanitizer: heap-use-after-free ...\wine\include\wine\list.h:100 in list_remove
Shadow bytes around the buggy address:
0x7f07e3ae0280: fd fd fd fa fa fa fa fa 00 00 00 00 00 00 00 00
0x7f07e3ae0300: 06 fa fa fa fa fa fd fd fd fd fd fd fd fd fd fd
0x7f07e3ae0380: fa fa fa fa fd fd fd fd fd fd fd fd fd fa fa fa
0x7f07e3ae0400: fa fa 00 00 00 00 00 00 00 00 06 fa fa fa fa fa
0x7f07e3ae0480: fd fd fd fd fd fd fd fd fd fd fa fa fa fa 00 00
=>0x7f07e3ae0500: 00 00 00 00 00 00 04 fa fa fa fa fa fd[fd]fd fd
0x7f07e3ae0580: fd fd fd fd fd fa fa fa fa fa fd fd fd fd fd fd
0x7f07e3ae0600: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fd
0x7f07e3ae0680: fd fa fa fa fa fa fd fd fd fd fd fd fd fd fd fa
0x7f07e3ae0700: fa fa fa fa fd fd fd fd fd fd fd fd fd fa fa fa
0x7f07e3ae0780: fa fa fd fd fd fd fd fd fd fd fd fd fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==control.exe==536==ABORTING
```
</details>
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/7719
On Wed Apr 2 01:09:11 2025 +0000, Yeshun Ye wrote:
> Subjectively, I do believe it is indeed an issue with FreeType, as its
> documentation does not explicitly specify how to handle the high 32
> bits. I submitted the patch to Wine simply because I am more familiar
> with Wine. Since you think this approach is inappropriate, I will try
> submitting the patch to FreeType instead. Should I close this merge
> request now?
Yes, let's close this MR. If the freetype folks push back, we can reopen it.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/7633#note_99643
x86_64 Windows and macOS both use `%gs` to access thread-specific data (Windows TEB, macOS TSD). To date, Wine has worked around this conflict by filling the most important TEB fields (`0x30`/`Self`, `0x58`/`ThreadLocalStorage`) in the macOS TSD structure (Apple reserved the fields for our use). This was sufficient for most Windows apps.
CrossOver's Wine had an additional hack to handle `0x60`/`ProcessEnvironmentBlock`, and binary patches for certain CEF binaries which directly accessed `0x8`/`StackBase`. Additionally, Apple's libd3dshared could activate a special mode in Rosetta 2 where code executing in certain regions would use the Windows TEB when accessing `%gs`.
Now that the PE separation is complete, GSBASE can be swapped when entering/exiting PE code. This is done in the syscall dispatcher, unix-call dispatcher, and for user-mode callbacks. GSBASE also needs to be set to the macOS TSD when entering signal handlers (in `init_handler()`), and then restored to the Windows TEB when exiting (in `leave_handler()`).
Some changes to the syscall dispatcher were needed to ensure that the TEB is not accessed through `%gs` while on the kernel stack (since a SIGUSR1 while on the kernel stack will result in GSBASE being set to the TSD).
---
I've tested this successfully on macOS 15 (Apple Silicon and Intel) and macOS 10.13 with several apps and games, including the `cefclient.exe` CEF sample.
Encouragingly, in some simple tests I didn't see a noticeable performance regression from this MR.
There are drawbacks though:
- libraries which jump directly from PE code into Unix code (expecting that %gs is always pointing to the macOS TSD) will crash. Notable examples are D3DMetal and DXMT. These will need to be changed to use Unix calls.
- If Windows code uses the `syscall` instruction directly, the stack pointer likely needs to be valid (which is probably not true on Windows). This is due to the syscall dispatcher saving registers onto the user stack and having to call `_thread_set_tsd_base`. I can't say I've ever seen direct syscalls done with an invalid `%rsp`, but it seems like something anticheat code might do.
---
macOS does not have a public API for setting GSBASE, but the private `_thread_set_tsd_base()` works and was added in macOS 10.12.
`_thread_set_tsd_base()` is a small thunk that sets `%esi`, `%eax`, and does the `syscall`: https://github.com/apple-oss-distributions/xnu/blob/8d741a5de7ff4191bf97d57….
The syscall instruction itself clobbers `%rcx` and `%r11`.
I've tried to save as few registers as possible when calling `_thread_set_tsd_base()`, but there may be room for improvement there.
---
I also tested an alternate implementation strategy for this which took advantage of the expanded "full" thread state which is passed to signal handlers when a process has set a user LDT. The full thread state includes GSBASE, so GSBASE is set back to whatever is in the sigcontext on return (like every other field in the context). This would avoid needing to explicitly reset GSBASE in `leave_handler()`.
This strategy was simpler, but I'm not using it for 2 reasons:
- the "full" thread state is only available starting with macOS 10.15, and we still support 10.13.
- more crucially, Rosetta 2 doesn't seem to correctly implement the GS.base field of the full thread state. It's set to 0 on entry, and isn't read on exit.
--
v7: ntdll: Remove x86_64 Mac-specific TEB access workarounds that are no longer needed.
ntdll: On macOS x86_64, swap GSBASE between the TEB and macOS TSD when entering/leaving PE code.
ntdll: Set %rsp to be inside syscall_frame before accessing %gs in x86_64 syscall dispatcher.
ntdll: Don't access the TEB through %gs when using the kernel stack in x86_64 syscall dispatcher.
ntdll: Ensure init_handler runs in signal handlers before any compiler-generated memset calls.
ntdll: Remove ugly fallback method for getting a thread's GSBASE on macOS.
https://gitlab.winehq.org/wine/wine/-/merge_requests/6866
In `generate_font_link_info`, because the return value of
`GdipCreateFontFromDC` is not checked, section->font might be set to NULL.
`GdipMeasureString` calls `gdip_format_string`, which then calls
`generate_font_link_info` and `font_link_get_text_extent_point`. In
`font_link_get_text_extent_point`, the font from `gdip_font_link_section` is also
not checked for NULL, which may cause a crash.
Therefore, in `generate_font_link_info`, when `GdipCreateFontFromDC` fails,
store `(GpFont *)base_font` (as with `IMLangFontLink_MapFont` failure) to ensure
the font in `gdip_font_link_section` is valid.
---
This issue was reproduced while using the [QQ Music](https://y.qq.com/download/index.html).
Below is the original winedbg log (on Wine 10.4 + wine-staging + DXVK,
with some native libraries used. If needed and permitted by WineHQ, I will list them.)
(PS: This issue should also be reproduced using generic wine master without third parties)
```
Wine-dbg>frame 1
Wine-dbg>bt
Backtrace:
0 0x00000078ed4d58 get_font_hfont+0x30(graphics=<couldn't compute location>, font=<couldn't compute location>, format=<couldn't compute location>, hfont=<couldn't compute location>, lfw_return=<couldn't compute
location>, matrix=<couldn't compute location>) [/home/up/wine/build32/../wine/dlls/gdiplus/graphics.c:2476] in gdiplus (0x0000000073f700)
=>1 0x00000078ed21bd font_link_get_text_extent_point+0xb9(info=000000000073F774, index=0, length=0xb, max_ext=0x7fffff83, fit=000000000073F7CC, size=000000000073F7B0) [/home/up/wine/build32/../wine/dlls/gdiplus/g
raphics.c:5537] in gdiplus (0x0000000073f74c)
2 0x00000078ed340d gdip_format_string+0x2f9(graphics=0000000003665DD0, hdc=0000000034010075, string=L"Q音听我想听的歌???", length=0xb, font=0000000003672700, rect=000000000073F864, format=0000000009FEB508, ignore_empt
y_clip=0x1, callback=0000000078EDADC8, user_data=000000000073F878) [/home/up/wine/build32/../wine/dlls/gdiplus/graphics.c:5663] in gdiplus (0x0000000073f81c)
3 0x00000078ea8283 GdipMeasureString+0x3cb(graphics=<couldn't compute location>, string=<couldn't compute location>, length=<couldn't compute location>, font=<couldn't compute location>, rect=<couldn't compute
location>, format=<couldn't compute location>, bounds=<couldn't compute location>, codepointsfitted=<couldn't compute location>, linesfilled=<couldn't compute location>) [/home/up/wine/build32/../wine/dlls/gdiplu
s/graphics.c:6050] in gdiplus (0x0000000073f8c0)
4 0x00000077d41fd2 in qqmusic (+0x31fd2) (0x0000000073f908)
5 0x00000077d3e1c6 in qqmusic (+0x2e1c6) (0x0000000073f96c)
6 0x00000077d3dd11 in qqmusic (+0x2dd11) (0x0000000073f9f8)
7 0x00000077f29bd4 in qqmusic (+0x219bd4) (0x0000000073fa70)
8 0x00000077f29a63 in qqmusic (+0x219a63) (0x0000000073faa0)
9 0x00000077f28760 in qqmusic (+0x218760) (0x0000000073fb08)
10 0x00000077b059d7 in common (+0x1059d7) (0x0000000073fb94)
11 0x00000077b06c35 in common (+0x106c35) (0x0000000073fbc8)
12 0x0000007a038b48 in user32 (+0x8b48) (0x0000000073fbf8)
13 0x0000007a093e43 call_window_proc+0xa7(hwnd=0000000000060138, msg=0x113, wp=0x400, lp=0, result=000000000073FC68, arg=0000000077B06B90) [/home/up/wine/build32/../wine/dlls/user32/winproc.c:111] in user32 (0x
0000000073fc40)
14 0x0000007a09c066 dispatch_win_proc_params+0xce(params=000000000073FCA0) [/home/up/wine/build32/../wine/dlls/user32/winproc.c:710] in user32 (0x0000000073fc7c)
15 0x0000007a09be4a dispatch_message+0x9e(msg=000000000073FDCC, ansi=0) [/home/up/wine/build32/../wine/dlls/user32/message.c:804] in user32 (0x0000000073fcd8)
16 0x0000007a04f530 DispatchMessageW+0xff(msg=000000000073FDCC) [/home/up/wine/build32/../wine/dlls/user32/message.c:890] in user32 (0x0000000073fd60)
17 0x000000780c001d in qqmusic (+0x3b001d) (0x0000000073fe38)
18 0x000000780c0ce6 in qqmusic (+0x3b0ce6) (0x0000000073fea8)
19 0x00000000403af4 in qqmusic (+0x3af4) (0x0000000073fefc)
20 0x00000000403bd6 in qqmusic (+0x3bd6) (0x0000000073ff50)
21 0x0000007bcdeb10 in kernel32 (+0xeb10) (0x0000000073ff68)
22 0x0000007be0d083 in ntdll (+0xd083) (0x0000000073ff78)
23 0x0000007be435b2 call_thread_func+0x2e(entry=000000000040678E, arg=00000000003F1000) [/home/up/wine/build32/../wine/dlls/ntdll/signal_i386.c:526] in ntdll (0x0000000073ffec)
Wine-dbg>info locals
0x00000078ed21bd font_link_get_text_extent_point+0xb9: (0073f74c)
struct gdip_format_string_info* info=000000000073F774 (parameter [EBP+8])
INT index=0 (parameter [EBP+12])
int length=0xb (parameter [EBP+16])
int max_ext=0x7fffff83 (parameter [EBP+20])
LPINT fit=000000000073F7CC (parameter [EBP+24])
SIZE* size=000000000073F7B0 (parameter [EBP+28])
DWORD to_measure_length=0x3 (local [EBP-16])
HFONT hfont=000000000D0A00AE (local [EBP-24])
HFONT oldhfont=000000004C0A00B0 (local [EBP-20])
SIZE sizeaux={cx=0x7c, cy=0x13} (local [EBP-32])
int i=0x8 (local [EBP-8])
int fitaux=0x8 (local [EBP-36])
struct gdip_font_link_section* section=00000000037E31A8 (local [EBP-12])
Wine-dbg>p *section
Exception c0000005
Wine-dbg>x/10x 0x00000000037E31A8
0x000000037e31a8: 0073f78c 037e3188 00000008 0000000b
0x000000037e31b8: 00000000 00000000 00000004 8146001b
0x000000037e31c8: 78e0c030 78e0c030
```
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/7700
On Wed Apr 2 01:09:11 2025 +0000, Huw Davies wrote:
> Could you explain why we need this? Why does it matter how freetype is
> compiled; isn't that an ABI breakage on their side?
Subjectively, I do believe it is indeed an issue with FreeType, as its documentation does not explicitly specify how to handle the high 32 bits. I submitted the patch to Wine simply because I am more familiar with Wine. Since you think this approach is inappropriate, I will try submitting the patch to FreeType instead. Should I close this merge request now?
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/7633#note_99632