[Bug 12757] Europa Universalis Rome crashes on startup (D3DXLoadSurfaceFromFileInMemory must not unconditionally call CoUninitialize(), different COM threading model used)
wine-bugs at winehq.org
wine-bugs at winehq.org
Sun Feb 23 13:26:13 CST 2014
https://bugs.winehq.org/show_bug.cgi?id=12757
Anastasius Focht <focht at gmx.net> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|REOPENED |NEW
CC| |focht at gmx.net
Summary|Europa Universalis Rome: |Europa Universalis Rome
|Crashes on start-up |crashes on startup
| |(D3DXLoadSurfaceFromFileInM
| |emory must not
| |unconditionally call
| |CoUninitialize(), different
| |COM threading model used)
--- Comment #20 from Anastasius Focht <focht at gmx.net> ---
Hello folks,
confirming - although this bug has been recycled at least once for different
issues.
The game uses a multi-threaded apartment on its main thread.
Multiple Wine components/API create apartment-threaded COM inproc servers on
the same thread (dsound, d3dx, ...).
The caller needs to be aware of this situation (RPC_E_CHANGED_MODE) in order to
avoid messing up the coinit refcount.
The visible part is the infamous 'Attempt to change threading model of this
apartment from multi-threaded to apartment threaded' message in terminal.
Relevant part of trace log:
The game creates multi-threaded apartment and quartz instance:
--- snip ---
0025:Call ole32.CoInitializeEx(00000000,0000000c) ret=00897417
...
0025:Ret ole32.CoInitializeEx() retval=00000000 ret=00897417
...
0025:Call ole32.CoCreateInstance(00a37470,00000000,00000003,00a37420,00e454d8)
ret=008317a7
...
0025:Call KERNEL32.LoadLibraryExW(0033ee8e
L"C:\\windows\\system32\\quartz.dll",00000000,00000008) ret=7eb6a6cb
...
0025:Ret PE DLL (proc=0x7d2c1b70,module=0x7d210000
L"quartz.dll",reason=PROCESS_ATTACH,res=(nil)) retval=1
0025:Ret KERNEL32.LoadLibraryExW() retval=7d210000 ret=7eb6a6cb
...
0025:Ret ole32.CoCreateInstance() retval=00000000 ret=008317a7
--- snip ---
Wine uses multiple COM servers on the same thread with apartment threading
model:
--- snip ---
...
0025:Call dsound.DirectSoundCreate8(00000000,00de1880,00000000) ret=0082f977
...
0025:Call ole32.CoInitialize(00000000) ret=7e2ce081
0025:err:ole:CoInitializeEx Attempt to change threading model of this apartment
from multi-threaded to apartment threaded
0025:Ret ole32.CoInitialize() retval=80010106 ret=7e2ce081
0025:Call ole32.CoCreateInstance(7e2e27d8,00000000,00000001,7e2e27a8,0033efa8)
ret=7e2ce0b6
...
--- snip ---
The problematic one:
--- snip ---
...
0025:trace:d3dx:D3DXLoadSurfaceFromFileInMemory dst_surface 0xb34afa8,
dst_palette (nil), dst_rect (null), src_data 0x1570000, src_data_size 65580,
src_rect (null), filter 0x1, color_key 0x00000000, src_info (nil).
0025:trace:d3dx:D3DXGetImageInfoFromFileInMemory (0x1570000, 65580, 0x33ea64)
0025:Call ole32.CoInitializeEx(00000000,00000002) ret=7ed82a47
0025:err:ole:CoInitializeEx Attempt to change threading model of this apartment
from multi-threaded to apartment threaded
0025:Ret ole32.CoInitializeEx() retval=80010106 ret=7ed82a47
0025:Call ole32.CoCreateInstance(7ed9ed1c,00000000,00000001,7ed9ed2c,0033e8cc)
ret=7ed82a7f
...
0025:trace:d3dx:D3DXLoadSurfaceFromMemory (0xb34afa8, (nil), (null), 0xb361c10,
0x16, 512, (nil), (0,0)-(128,128) 0x1, 0x00000000)
...
0025:Call ole32.CoUninitialize() ret=7ed84242
0025:Call quartz.DllCanUnloadNow() ret=7eb6c1c3
0025:Call rpcrt4.NdrDllCanUnloadNow(7d30bab8) ret=7d2633fd
0025:Ret rpcrt4.NdrDllCanUnloadNow() retval=00000000 ret=7d2633fd
0025:Ret quartz.DllCanUnloadNow() retval=00000000 ret=7eb6c1c3
0025:Call KERNEL32.FreeLibrary(7d210000) ret=7eb6aa42
0025:Call PE DLL (proc=0x7d2c1b70,module=0x7d210000
L"quartz.dll",reason=PROCESS_DETACH,res=(nil))
0025:Ret PE DLL (proc=0x7d2c1b70,module=0x7d210000
L"quartz.dll",reason=PROCESS_DETACH,res=(nil)) retval=1
0025:Call PE DLL (proc=0x7dcc9d1c,module=0x7dcb0000
L"msvfw32.dll",reason=PROCESS_DETACH,res=(nil))
0025:Ret PE DLL (proc=0x7dcc9d1c,module=0x7dcb0000
L"msvfw32.dll",reason=PROCESS_DETACH,res=(nil)) retval=1
0025:Call PE DLL (proc=0x7cd1c3bc,module=0x7cc60000
L"comctl32.dll",reason=PROCESS_DETACH,res=(nil))
...
--- snip ---
At this point 'quartz.dll' is unloaded from memory but the game still holds COM
class/iface references!
The crash is a late manifestation, it tries to call
quartz.BasicAudio_put_Volume() with the PE image already gone.
Wine code like D3DXGetImageInfoFromFileInMemory() does it right, taking
CoInitializeEx() result into account.
The COM threading model used might be still questionable.
Source:
http://source.winehq.org/git/wine.git/blob/fa8a0dc7f61715a093a3b2e4453e843a4129476e:/dlls/d3dx9_36/surface.c#l1023
--- snip ---
1023 HRESULT WINAPI D3DXLoadSurfaceFromFileInMemory(IDirect3DSurface9
*pDestSurface,
1024 const PALETTEENTRY *pDestPalette, const RECT *pDestRect, const void
*pSrcData, UINT SrcDataSize,
1025 const RECT *pSrcRect, DWORD dwFilter, D3DCOLOR Colorkey,
D3DXIMAGE_INFO *pSrcInfo)
1026 {
...
1081 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1082
1083 if (FAILED(CoCreateInstance(&CLSID_WICImagingFactory, NULL,
CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&factory)))
1084 goto cleanup_err;
...
1180 cleanup_err:
1181 if (factory)
1182 IWICImagingFactory_Release(factory);
1183
1184 CoUninitialize();
...
--- snip ---
With that bug fixed it runs farther - and crashes again due to another d3dx9_36
insufficiency.
$ sha1sum Rome_Demo.exe
57e1fc8f2a1b8eeb0a1ccff218010eb828b00159 Rome_Demo.exe
$ du -sh Rome_Demo.exe
308M Rome_Demo.exe
$ wine --version
wine-1.7.13-27-ge610713
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