Hi list,
Does anyone know why _getptd() calls would return zero on a DLL that has been reloaded? Does something happen to the TLS used by _getptd?
At Muse Research we have been struggling with a deep bug for years where there is a crash _sometimes_ if you load a DLL a second time.
Finally (with a big tip of the hat to Julien Pommier at PianoTeq!) we have a test case that demonstrates a (if not _the_) crash.
The sequence is: 1. [main] start a thread 2. [main] load a library 3. [thread] call std::cout<< from the library 4. [main] free the library 5. [main] reload the library 6. [thread] call std::cout<< from the library -> crash!
It looks like the crash happens because the MSVCRT function _getptd() is returning zero in step 6. This is dereferenced and crashes. In windows, there is no crash.
The library in question is using static vc runtime linkage, so _getptd() is linked in and I don't know exactly what it is doing. But Wine's MSVCRT implementation of _getptd() gets its data from TlsGetValue. And I can see that just before the crash there is a TlsGetValue call that returns zero.
Looking at TlsGetValue(), there must be something wrong with the values in TlsSlots. Maybe they persist for DLLs in Windows in a way they don't for Wine...? Or maybe Wine doesn't reinitialize them the same way when the DLL is reloaded?
Any hints, thoughts? clues? Thanks!
-- Michael Ost
Am 11.01.2013 20:24, schrieb Michael Ost:
Hi list,
Does anyone know why _getptd() calls would return zero on a DLL that has been reloaded? Does something happen to the TLS used by _getptd?
At Muse Research we have been struggling with a deep bug for years where there is a crash _sometimes_ if you load a DLL a second time.
Finally (with a big tip of the hat to Julien Pommier at PianoTeq!) we have a test case that demonstrates a (if not _the_) crash.
The sequence is:
- [main] start a thread
- [main] load a library
- [thread] call std::cout<< from the library
- [main] free the library
- [main] reload the library
- [thread] call std::cout<< from the library
-> crash!
Hi Michael, developers are sometimes quite lazy, provide some testcode (maybe shipping with an executable) and you have better chances, maybe file a bug, not sure.
On Fri, Jan 11, 2013 at 11:24:55AM -0800, Michael Ost wrote:
Hi list,
Does anyone know why _getptd() calls would return zero on a DLL that has been reloaded? Does something happen to the TLS used by _getptd?
At Muse Research we have been struggling with a deep bug for years where there is a crash _sometimes_ if you load a DLL a second time.
Finally (with a big tip of the hat to Julien Pommier at PianoTeq!) we have a test case that demonstrates a (if not _the_) crash.
The sequence is:
- [main] start a thread
- [main] load a library
- [thread] call std::cout<< from the library
- [main] free the library
- [main] reload the library
- [thread] call std::cout<< from the library
-> crash!
It looks like the crash happens because the MSVCRT function _getptd() is returning zero in step 6. This is dereferenced and crashes. In windows, there is no crash.
The library in question is using static vc runtime linkage, so _getptd() is linked in and I don't know exactly what it is doing. But Wine's MSVCRT implementation of _getptd() gets its data from TlsGetValue. And I can see that just before the crash there is a TlsGetValue call that returns zero.
Looking at TlsGetValue(), there must be something wrong with the values in TlsSlots. Maybe they persist for DLLs in Windows in a way they don't for Wine...? Or maybe Wine doesn't reinitialize them the same way when the DLL is reloaded?
Any hints, thoughts? clues? Thanks!
Is this statically linked msvcrt from Wine or Windows?
And why free/reload a statically linked library?
Ciao, Marcus
On 1/13/13 1:17 PM, Marcus Meissner wrote:
On Fri, Jan 11, 2013 at 11:24:55AM -0800, Michael Ost wrote:
Hi list,
Does anyone know why _getptd() calls would return zero on a DLL that has been reloaded? Does something happen to the TLS used by _getptd?
At Muse Research we have been struggling with a deep bug for years where there is a crash _sometimes_ if you load a DLL a second time.
Finally (with a big tip of the hat to Julien Pommier at PianoTeq!) we have a test case that demonstrates a (if not _the_) crash.
The sequence is:
- [main] start a thread
- [main] load a library
- [thread] call std::cout<< from the library
- [main] free the library
- [main] reload the library
- [thread] call std::cout<< from the library
-> crash!
It looks like the crash happens because the MSVCRT function _getptd() is returning zero in step 6. This is dereferenced and crashes. In windows, there is no crash.
The library in question is using static vc runtime linkage, so _getptd() is linked in and I don't know exactly what it is doing. But Wine's MSVCRT implementation of _getptd() gets its data from TlsGetValue. And I can see that just before the crash there is a TlsGetValue call that returns zero.
Looking at TlsGetValue(), there must be something wrong with the values in TlsSlots. Maybe they persist for DLLs in Windows in a way they don't for Wine...? Or maybe Wine doesn't reinitialize them the same way when the DLL is reloaded?
Any hints, thoughts? clues? Thanks!
Is this statically linked msvcrt from Wine or Windows?
It's statically linked in Windows.
And why free/reload a statically linked library?
We load and unload the DLL that has MSCVRT statically linked into it. Our program is a "plugin player", that loads (and unloads) VST sound plugins for musicians to perform with.
-- mo
On 1/14/2013 01:59, Michael Ost wrote:
On 1/13/13 1:17 PM, Marcus Meissner wrote:
On Fri, Jan 11, 2013 at 11:24:55AM -0800, Michael Ost wrote:
Hi list,
Does anyone know why _getptd() calls would return zero on a DLL that has been reloaded? Does something happen to the TLS used by _getptd?
At Muse Research we have been struggling with a deep bug for years where there is a crash _sometimes_ if you load a DLL a second time.
Finally (with a big tip of the hat to Julien Pommier at PianoTeq!) we have a test case that demonstrates a (if not _the_) crash.
The sequence is:
- [main] start a thread
- [main] load a library
- [thread] call std::cout<< from the library
- [main] free the library
- [main] reload the library
- [thread] call std::cout<< from the library
-> crash!
It looks like the crash happens because the MSVCRT function _getptd() is returning zero in step 6. This is dereferenced and crashes. In windows, there is no crash.
The library in question is using static vc runtime linkage, so _getptd() is linked in and I don't know exactly what it is doing. But Wine's MSVCRT implementation of _getptd() gets its data from TlsGetValue. And I can see that just before the crash there is a TlsGetValue call that returns zero.
Looking at TlsGetValue(), there must be something wrong with the values in TlsSlots. Maybe they persist for DLLs in Windows in a way they don't for Wine...? Or maybe Wine doesn't reinitialize them the same way when the DLL is reloaded?
Any hints, thoughts? clues? Thanks!
Is this statically linked msvcrt from Wine or Windows?
It's statically linked in Windows.
And why free/reload a statically linked library?
We load and unload the DLL that has MSCVRT statically linked into it. Our program is a "plugin player", that loads (and unloads) VST sound plugins for musicians to perform with.
Not sure if it's related but wine's msvcrt doesn't like to be unloaded, so LdrAddRefDll() is used to prevent that. If I remember correctly there was a problem with messed up standard handles or something like that.
-- mo