[Bug 49260] Some MFC applications using CPropertySheet freeze in CPropertySheet::DoModal on Mac OS X

WineHQ Bugzilla wine-bugs at winehq.org
Wed May 27 08:11:19 CDT 2020


https://bugs.winehq.org/show_bug.cgi?id=49260

Anastasius Focht <focht at gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |focht at gmx.net
            Summary|Protection c0000005 with    |Some MFC applications using
                   |MFC CPropertySheet::DoModal |CPropertySheet freeze in
                   |                            |CPropertySheet::DoModal on
                   |                            |Mac OS X

--- Comment #1 from Anastasius Focht <focht at gmx.net> ---
Hello Reinhold,

the exceptions are by design. The app makes use of LocalXXX() API in message
handler(s) and sometimes passes NULL handle (HLOCAL) to GlobalLock(). Wine
needs to figure out if the handle is a valid pointer and you basically trace
the result of the access with 'seh' debug channel.

Disassembly of one location where the API is used by your example app:

--- snip ---
0000000140007988 | mov qword ptr ss:[rsp+8],rbx           |
000000014000798D | mov qword ptr ss:[rsp+10],rbp          |
0000000140007992 | mov qword ptr ss:[rsp+18],rsi          |
0000000140007997 | push rdi                               |
0000000140007998 | sub rsp,20                             |
000000014000799C | mov rdi,rdx                            |
000000014000799F | mov rbx,rcx                            |
00000001400079A2 | call newpropertysheet.14000A034        |
00000001400079A7 | xor ebp,ebp                            |
00000001400079A9 | test eax,eax                           |
00000001400079AB | je newpropertysheet.1400079B7          |
00000001400079AD | mov eax,1                              |
00000001400079B2 | jmp newpropertysheet.140007A91         |
00000001400079B7 | mov rdx,qword ptr ds:[1401E9370]       | "AfxClosePending"
00000001400079BE | mov rcx,qword ptr ds:[rbx+40]          |
00000001400079C2 | call qword ptr ds:[140168EF0]          | GetPropA
00000001400079C8 | mov rcx,rax                            |
00000001400079CB | mov rsi,rax                            | can be NULL
00000001400079CE | call qword ptr ds:[140168868]          | GlobalLock
00000001400079D4 | test rax,rax                           |
00000001400079D7 | je newpropertysheet.140007A3A          |
00000001400079D9 | cmp dword ptr ds:[rax],1               |
00000001400079DC | jne newpropertysheet.140007A31         |
00000001400079DE | mov rcx,qword ptr ds:[rbx+40]          |
00000001400079E2 | xor r9d,r9d                            |
00000001400079E5 | xor r8d,r8d                            |
00000001400079E8 | mov edx,476                            |
00000001400079ED | call qword ptr ds:[140169098]          | SendMessageA
00000001400079F3 | test rax,rax                           |
00000001400079F6 | jne newpropertysheet.140007A31         |
00000001400079F8 | mov rcx,rsi                            |
00000001400079FB | call qword ptr ds:[140168770]          | GlobalUnlock
0000000140007A01 | mov rdx,qword ptr ds:[1401E9370]       | "AfxClosePending"
0000000140007A08 | mov rcx,qword ptr ds:[rbx+40]          | 
0000000140007A0C | call qword ptr ds:[140168EF8]          | RemovePropA
0000000140007A12 | test rax,rax                           |
0000000140007A15 | je newpropertysheet.140007A20          |
0000000140007A17 | mov rcx,rax                            |
0000000140007A1A | call qword ptr ds:[<&JMP.&GlobalFree>] |
0000000140007A20 | mov rax,qword ptr ds:[rbx]             |
0000000140007A23 | mov rcx,rbx                            |
0000000140007A26 | call qword ptr ds:[rax+C0]             |
0000000140007A2C | jmp newpropertysheet.1400079AD         |
0000000140007A31 | mov rcx,rsi                            |
0000000140007A34 | call qword ptr ds:[140168770]          | GlobalUnlock
0000000140007A3A | cmp dword ptr ds:[rdi+8],100           |
0000000140007A41 | jne newpropertysheet.140007A86         |
0000000140007A43 | mov ecx,11                             |
0000000140007A48 | call qword ptr ds:[140168F00]          | GetAsyncKeyState
0000000140007A4E | test ax,ax                             |
0000000140007A51 | jns newpropertysheet.140007A86         |
0000000140007A53 | cmp qword ptr ds:[rdi+10],9            |
0000000140007A58 | je newpropertysheet.140007A68          |
0000000140007A5A | cmp qword ptr ds:[rdi+10],21           |
0000000140007A5F | je newpropertysheet.140007A68          |
0000000140007A61 | cmp qword ptr ds:[rdi+10],22           |
0000000140007A66 | jne newpropertysheet.140007A86         |
0000000140007A68 | mov rcx,qword ptr ds:[rbx+40]          |
0000000140007A6C | mov r9,rdi                             |
0000000140007A6F | xor r8d,r8d                            |
0000000140007A72 | mov edx,475                            |
0000000140007A77 | call qword ptr ds:[140169098]          | SendMessageA
0000000140007A7D | test rax,rax                           |
0000000140007A80 | jne newpropertysheet.1400079AD         |
0000000140007A86 | mov rdx,rdi                            |
0000000140007A89 | mov rcx,rbx                            |
0000000140007A8C | call newpropertysheet.14000B578        |
0000000140007A91 | mov rbx,qword ptr ss:[rsp+30]          |
0000000140007A96 | mov rbp,qword ptr ss:[rsp+38]          |
0000000140007A9B | mov rsi,qword ptr ss:[rsp+40]          |
0000000140007AA0 | add rsp,20                             |
0000000140007AA4 | pop rdi                                |
0000000140007AA5 | ret                                    |
--- snip ---

https://source.winehq.org/git/wine.git/blob/8257fe88fb99ca0bdeec27b47b7cf835bda5c061:/dlls/kernelbase/memory.c#l684

--- snip ---
 684 /***********************************************************************
 685  *           LocalLock   (kernelbase.@)
 686  */
 687 LPVOID WINAPI DECLSPEC_HOTPATCH LocalLock( HLOCAL hmem )
 688 {
 689     void *ret = NULL;
 690 
 691     if (is_pointer( hmem ))
 692     {
 693         __TRY
 694         {
 695             volatile char *p = hmem;
 696             *p |= 0;
 697         }
 698         __EXCEPT_PAGE_FAULT
 699         {
 700             return NULL;
 701         }
 702         __ENDTRY
 703         return hmem;
 704     }
 705 
 706     RtlLockHeap( GetProcessHeap() );
 707     __TRY
 708     {
 709         struct local_header *header = get_header( hmem );
 710         if (header->magic == MAGIC_LOCAL_USED)
 711         {
 712             ret = header->ptr;
 713             if (!header->ptr) SetLastError( ERROR_DISCARDED );
 714             else if (header->lock < LMEM_LOCKCOUNT) header->lock++;
 715         }
 716         else
 717         {
 718             WARN( "invalid handle %p (magic: 0x%04x)\n", hmem,
header->magic );
 719             SetLastError( ERROR_INVALID_HANDLE );
 720         }
 721     }
 722     __EXCEPT_PAGE_FAULT
 723     {
 724         WARN("(%p): Page fault occurred ! Caused by bug ?\n", hmem);
 725         SetLastError( ERROR_INVALID_HANDLE );
 726     }
 727     __ENDTRY
 728     RtlUnlockHeap( GetProcessHeap() );
 729     return ret;
 730 }
--- snip ---

Emphasis on line 696 which causes the page fault you see.

Alexandre changed that piece of code in commit
https://source.winehq.org/git/wine.git/commit/a76518c186ac0893ea460cd3b061096f1b05c8cc?f=dlls/kernelbase/memory.c
("kernelbase: Use exception handlers instead of IsBad* functions.").

One could argue the value could be checked for NULL first to avoid the page
fault at all. Still, it shouldn't change the outcome. These exceptions are not
visible to the app. The app doesn't install vectored exception handler / VEH.

Please provide a link to an app which shows the "freeze" behaviour (and steps
to reproduce).

Regards

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.



More information about the wine-bugs mailing list