Has anyone seen a deadlock in unit initialization in a FMX app when using runtime packages?

Has anyone seen a deadlock in unit initialization in a FMX app when using runtime packages?

I can reproduce this in XE4 like so:
 - New FMX app.  Make is 3D, have a 3D form.
 - Project Options > Packages > Runtime Packages > All configurations (32-bit Windows platform) > Link with runtime packages - set to True
Run the app.  About 50% of the time, you will get a deadlock with two threads, each in a method called by System.InitUnits.

Here's the really weird thing (apart from it being two threads each init-ing units.)  InitUnits looks after the unit initialization code, ie calling whatever is in the initialization section.  The second time InitUnits is called, from a second thread this time, it has more units to loop through than before (152 vs 291.)  And, the unit that is causing the deadlock is - wait for it - Vcl.Controls.  Yes, VCL.  Why is that unit ever loaded in a brand new FMX app?

I was puzzling over this for quite some time in a FMX app where I need to load the FMX package at runtime (so any solution would be really appreciated.)  But as I said, I reproduced this just now with a brand new, from-scratch FMX app too.

Edit: the deadlock itself is caused because in the second thread, it called into (VCL) TApplication.Create; IsLibrary is false (should it be for a runtime package?) and it calls OleInitialize.  At the same time the first thread is calling OleInitialize from FMX.Platform.Win's initialization section.  But, I'm still puzzled by (a) where the second thread is coming from; (b) why the VCL is being loaded by a FMX runtime-packaged app.

Callstack of the first thread:
:7758f8d1 ntdll.ZwWaitForSingleObject + 0x15
:775a8d28 ; ntdll.dll
:775ac401 ; ntdll.dll
:775ac558 ntdll.LdrLoadDll + 0x7b
:75bf2c95 ; C:\Windows\syswow64\KERNELBASE.dll
:754eaac3 ; C:\Windows\syswow64\USER32.dll
:7758010a ntdll.KiUserCallbackDispatcher + 0x2e
:754eaa3c ; C:\Windows\syswow64\USER32.dll
:754e8a5c USER32.CreateWindowExW + 0x33
:76f5644f ; C:\Windows\syswow64\ole32.dll
:76f50b81 ; C:\Windows\syswow64\ole32.dll
:76f2ed55 ; C:\Windows\syswow64\ole32.dll
:76f2efe6 ole32.OleInitialize + 0xf
fmx.FMX.Platform.Win.FMX.Platform.Win
rtl.System.InitUnits
rtl.System._StartExe(???,???)
SysInit._InitExe($401F50)
Project2.Project2
:758c338a kernel32.BaseThreadInitThunk + 0x12
:775a9f72 ntdll.RtlInitializeExceptionChain + 0x63
:775a9f45 ntdll.RtlInitializeExceptionChain + 0x36

Callstack of the second thread:
:7758f8d1 ntdll.ZwWaitForSingleObject + 0x15
:775a8d28 ; ntdll.dll
:775ac401 ; ntdll.dll
:775ac558 ntdll.LdrLoadDll + 0x7b
:75bf2c95 ; C:\Windows\syswow64\KERNELBASE.dll
:754eaac3 ; C:\Windows\syswow64\USER32.dll
:775a99a0 ; ntdll.dll
:775ad939 ; ntdll.dll
:775ad7fc ; ntdll.dll
:775ac558 ntdll.LdrLoadDll + 0x7b
:75bf2c95 ; C:\Windows\syswow64\KERNELBASE.dll
:754eaac3 ; C:\Windows\syswow64\USER32.dll
:7758010a ntdll.KiUserCallbackDispatcher + 0x2e
:754eaa3c ; C:\Windows\syswow64\USER32.dll
:754ed261 USER32.CreateWindowExA + 0x33
:74827708 ; C:\Windows\WinSxS\x86_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.7601.18120_none_72d2e82386681b36\gdiplus.dll
:7482792a ; C:\Windows\WinSxS\x86_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.7601.18120_none_72d2e82386681b36\gdiplus.dll
:7482787a ; C:\Windows\WinSxS\x86_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.7601.18120_none_72d2e82386681b36\gdiplus.dll
:758c338a kernel32.BaseThreadInitThunk + 0x12
:775a9f72 ntdll.RtlInitializeExceptionChain + 0x63
:775a9f45 ntdll.RtlInitializeExceptionChain + 0x36

Comments

  1. That's probably a light version of one of the AQTime products that ships with Delphi. They do funny things to processes and cause trouble when loading/unloading DLLs (and BPLs).

    ReplyDelete
  2. Jeroen Wiert Pluimers A good guess, but actually it was a beta version of a different person's plugin I was testing. I didn't want to say what it was publicly since as a beta it's not even publicly available yet.

    ReplyDelete

Post a Comment