http://bugs.winehq.org/show_bug.cgi?id=3756
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |focht@gmx.net
--- Comment #8 from Anastasius Focht focht@gmx.net 2008-09-02 09:01:16 --- Hello,
good bug ;-) This is another case of Wine using/managing heap(s) differently than Windows.
Wine uses the same process heap for all kinds of allocators - this leads to problems in conjunction with OLE related memory allocation.
Due to app bugs multiple double frees of SysXXX allocated memory (oleaut32) happen. Because of "interleaving" allocation calls from non-OLE stuff in between, which leads to reuse of previously freed blocks (shared heap), heap corruption takes place. The crashes happen some time later and the root cause is not obvious due to the nature of heap corruption.
I'll leave the glory memory dumps/block analysis out here because they would probably bore you anyway (hope you enjoyed bug 10368) ;-)
In short: This problem can be avoided by using the generic OLE allocator for SysXXX API and a private heap for OLE allocators.
The following hints can be found using g00gle:
(+SysAllocString +heap +CoTaskMemAlloc)
--- quote --- Turns out that SysAlloCString uses a 'special' heap managed by Ole32.Dll --- quote ---
--- quote --- CoTaskMemAlloc/Free do not use the same heap as the CRT. They use a dedicated heap created on your behalf when the OLE DLL loads. --- quote ---
--- quote --- BSTR's are usually created and free'd using SysAllocString and SysFreeString (there are some other SysxxxxString functions too). The reason for this is that COM owns the heap from which these strings reside meaning that you can safely pass them from one object to another. --- quote ---
--- quote --- First, on the SysAllocString and SysFreeString, they are just convenience functions to CoTaskMemAlloc and CoTaskMemFree. --- quote ---
I verified my findings and the google hints using the following changes:
- replaced HeapAlloc/HeapReAlloc/HeapFree calls of SysXXX family (oleaut32) with appropriate ole32 generic allocator calls to CoTaskMemAlloc/CoTaskMemRealloc/CoTaskMemFree - created a private heap in ole32 (Dllmain) - let any IMalloc_fnXXX functions use the private heap instead of GetProcessHeap()
With the changes applied, the app (IDE) successfully starts. This might also help other (buggy) apps which currently crash for no apparent reason (due to OLE double frees). Because heap corruption triggers crashes at random places this problem is not easy to diagnose and worse it's affected by various combinations of debug channels.
With the information given it should be easy for any takers to write a patch.
Regards