otya128 / winevdm

16-bit Windows (Windows 1.x, 2.x, 3.0, 3.1, etc.) on 64-bit Windows
GNU General Public License v2.0
2.65k stars 152 forks source link

Application hangs eventually after calling SetParent #1181

Open jgdrg opened 2 years ago

jgdrg commented 2 years ago

Describe the bug I have a legacy 3rd-party 16-bit application that calls SetParent to reparent a child window. The same application will run on Windows XP.

To demonstrate the issue I modified the Windows 3.1 SDK DDEML sample apps to call SetParent to reparent the Clock window in the Client. When I then interact with the client windows it will eventually hang.

Configure Winevdm/OTVDM

In otvdm.ini SeparateWOWVDM=0

Run test app

otvdmw ddeclk.exe otvdmw ddecl.exe In DDEML Client DDE -> Connect... Application: CLOCK Topic: WINDOW Connect DDE -> Start Transaction... Item: HANDLE Format: CF_TEXT Type: Request Ok Clock window will be reparented to Request window Resize this window to see clock inside Window -> Cascade conversations Try interacting with Clock|Window, eventually is should hang

Expected behavior No hang of UI.

Screenshots If applicable, add screenshots to help explain your problem. image image image image image image

Environment (please complete the following information):

Additional context Here is the DDEML source and binaries DDEML.zip

Trace trace.zip Some key highlights: DDEMLCLK thread creates window

1518:Call USER.41: CREATEWINDOW(131707f0 "DDEMLCLK",131707f0 "DDEMLCLK",00cf0000,8000,0000,0224,0245,0000,0000,1316,00000000)
allocate HANDLE 000E04A8=>0035

DDEML Client thread creates window that will be new parent

172c:Call USER.41: CREATEWINDOW(12170528 "InfoCtrl_class",1217053a "",54000000,000e,000c,00c8,0064,0052,0000,1216,121751dc)
allocate HANDLE 0003056C=>006e

Reparent DDEMLCLK window 172c:Call USER.233: SETPARENT(0035,006e)

Last log entry for DDEMLCLK thread 19d8:1518:trace:syslevel:_EnterSysLevel (759FADAC, level 1): thread 1518 count before 0

cracyc commented 2 years ago

Removing https://github.com/otya128/winevdm/blob/master/user/message.c#L3295 fixes it but breaks the watcom debugger. Windows sends message to the clock window thread which is blocked because the client window thread doesn't yield when peekmessage causes any sent messages to be processed.

jgdrg commented 2 years ago

Thanks for the quick response. I have tried comment out the PeekMessage but still are getting hangs. I've attached a video to demonstrate. DDEML Hang.zip

cracyc commented 2 years ago

Try https://github.com/otya128/winevdm/pull/1182

jgdrg commented 2 years ago

Thanks that has improve things, but still can get random hangs. I've attached a video of the latest plus the callstack when it happened. DDEML Clock Hang 2.zip DDEML Clock Hang 2 - Callstack.txt

cracyc commented 2 years ago

Try https://github.com/otya128/winevdm/pull/1182 after the newer commit.

jgdrg commented 2 years ago

Hi. Thanks for the this, it has fixed the hang we were seeing in the test app. But unfortunately we are still seeing intermittent hangs with the 3rd-party application. I have attached a callstack example of the hang. Hang-callstack-example.txt

We have full wine logs and crash dumps when the application hung, is there a way to provide this to you that will not be publicly accessible?

cracyc commented 2 years ago

What's probably happening here is setparent is attaching the message queues of 3140 and 17d8 threads. Since the 17d8 thread is in NtUserSetWindowPos, it's holding a lock that 3140 needs to continue but 3140 holds the win16mutex which blocks 17d8. I think the peekmessage in Getmessage32_16 needs to go for this to have any hope of working. I'm not going to make that change until a way to make it work with wdw is found but you can try it for your stuff.