On 01/12/2013 05:21 PM, Dan Kegel wrote:
The library in question is using static vc runtime linkage, so _getptd() is linked in
That's somewhat worrisome. So you have multiple instances of the C runtime library active in the same app?
Maybe you're not unloading that dll gracefully enough.
Might be heap corruption. I wonder if Valgrind might be helpful.
I second the suggestion to post a minimal testcase.
Here's a link to a zip file that includes the prebuilt .exe and .dll windows binaries that crash in wine. Plus the code.
https://dl.dropbox.com/u/97386125/msvcrt-dll-problem.zip
So, again, the bug is that MSVCRT calls are failing when called from a DLL that has been reloaded. If the calls come from a thread and if the DLL is built with static MSVCRT runtimes.
There is no crash for the program in Windows.
I also tried rebuilding the code for winelib, and it doesn't appear to have the same behavior. So the problem doesn't happen if Wine's MSVCRT is used, only if a windows DLL that uses static MSVCRT linkage is reloaded.
Thanks -- mo
On 01/15/13 00:32, Michael Ost wrote:
Here's a link to a zip file that includes the prebuilt .exe and .dll windows binaries that crash in wine. Plus the code.
The crash is caused by incomplete FlsFree implementation. There's a comment in it's code that says what needs to be added: /* FIXME: add equivalent of ThreadZeroTlsCell here */
I guess it would be best to create a bug describing this issue (http://bugs.winehq.org/).
Cheers, Piotr
On 01/15/2013 03:39 AM, Piotr Caban wrote:
On 01/15/13 00:32, Michael Ost wrote:
Here's a link to a zip file that includes the prebuilt .exe and .dll windows binaries that crash in wine. Plus the code.
The crash is caused by incomplete FlsFree implementation. There's a comment in it's code that says what needs to be added: /* FIXME: add equivalent of ThreadZeroTlsCell here */
Really? Are you sure that's it?
By the way, to aid my future Wine sleuthing, can you share any hints on how you figured this out?
I guess it would be best to create a bug describing this issue (http://bugs.winehq.org/).
OK. Do you know if it is acceptable form to post a windows binary as an example case on the bug? The DLL part of the bug has to be a windows binary.
Thanks for the tip! -- mo
On 1/15/13 7:59 PM, Michael Ost wrote:
On 01/15/2013 03:39 AM, Piotr Caban wrote:
The crash is caused by incomplete FlsFree implementation. There's a comment in it's code that says what needs to be added: /* FIXME: add equivalent of ThreadZeroTlsCell here */
Really? Are you sure that's it?
Yes. If you need a workaround to run you app you can comment FlsAlloc export. If this function is not available msvcrt will use TlsAlloc. I've also confirmed it by adding a hacky implementation of zeroing the memory on free.
By the way, to aid my future Wine sleuthing, can you share any hints on how you figured this out?
There's no easy answer to this question. I've looked on the relay log and after figuring out it may be related to Fls* functions I have added some more traces to it. Afterwards it was quite obvious that application was using a value that was supposed to be no longer valid (FlsGetValue was returning old pointer instead of NULL).
OK. Do you know if it is acceptable form to post a windows binary as an example case on the bug? The DLL part of the bug has to be a windows binary.
I think it's ok if it's your code and compiler license is allowing to publish produced executable. I've already seen some executables attached to bugs.
Piotr
On 01/15/2013 01:08 PM, Piotr Caban wrote:
On 1/15/13 7:59 PM, Michael Ost wrote:
On 01/15/2013 03:39 AM, Piotr Caban wrote:
The crash is caused by incomplete FlsFree implementation. There's a comment in it's code that says what needs to be added: /* FIXME: add equivalent of ThreadZeroTlsCell here */
Really? Are you sure that's it?
Yes. If you need a workaround to run you app you can comment FlsAlloc export. If this function is not available msvcrt will use TlsAlloc. I've
I can confirm that commenting out FlsAlloc does fix this crash. Wow!
Do you know what the implications are of using this hack? Would it simply be that any windows code that wants to use FlsAlloc would fail to load with a wine linkage error?
Also, is this what the VC runtimes that are statically compiled into a windows DLL do if FlsAlloc is unavailable? For backwards compatibility, I presume...?
also confirmed it by adding a hacky implementation of zeroing the memory on free.
Is the "hacky implementation" the line:
"if (NtCurrentTeb()->FlsSlots) NtCurrentTeb()->FlsSlots[index] = 0;"
that I see in FlsFree? Because, if so, that doesn't fix the crash. If not, I'd be interested in seeing your hack because we might just use it.
By the way, to aid my future Wine sleuthing, can you share any hints on how you figured this out?
There's no easy answer to this question. I've looked on the relay log and after figuring out it may be related to Fls* functions I have added some more traces to it. Afterwards it was quite obvious that application was using a value that was supposed to be no longer valid (FlsGetValue was returning old pointer instead of NULL).
Thanks for this work!
-- mo
On 01/15/13 22:36, Michael Ost wrote:
Do you know what the implications are of using this hack? Would it simply be that any windows code that wants to use FlsAlloc would fail to load with a wine linkage error?
Yes, any code that uses the function will fail while trying to call it.
Also, is this what the VC runtimes that are statically compiled into a windows DLL do if FlsAlloc is unavailable? For backwards compatibility, I presume...?
I guess it's for backwards compatibility.
Is the "hacky implementation" the line:
"if (NtCurrentTeb()->FlsSlots) NtCurrentTeb()->FlsSlots[index] = 0;"
It only clears the data in thread that calls FlsFree. It needs to be cleared in every thread that was using it.
that I see in FlsFree? Because, if so, that doesn't fix the crash. If not, I'd be interested in seeing your hack because we might just use it.
It was written just to check if it helps. It's not usable for anyone.