Unsolved Destructor of global variable in shared lib not called after QAudioDeviceInfo::availableDevices(QAudio::AudioOutput) or sending an HTTP(s) request using MSVC 2015
-
I think I found a weird issue while trying to get Visual Leak Detector and Windows CRT collecting the results when shutting down the app with latest Qt version 5.10.1. I created a minimal example that reproduces the issue. It seems I don't have enough privileges to upload an attachment, but you can find the example here: https://transfer.sh/13Fda2/QtTest.zip. This happens in both debug and release under Windows 10 using MSVC 2015 and Qt 5.10.1 32bit. I was also able to reproduce using MSVC 2015 Qt 5.9.4 32bit as well.
The idea is simple: just have a global variable in a shared library. I expect the destructor to be called when the library is unloaded when exiting the application. However, that doesn't happen if I call
QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)
or if I send an HTTP(s) request. Apart from setting a log trace, I have also verified that if I set a breakpoint, it doesn't get hit.For instance, in my example this is what happens when I don't call
availableDevices
:Lib::Lib() Lib::foo Using Qt version 5.10.1 Lib::~Lib()
Then, calling
availableDevices
:Lib::Lib() Lib::foo Using Qt version 5.10.1 "Speakers (High Definition Audio Device)" "Speakers (High Definition Audio Device)"
This same code works as expected and the destructor is called in both Linux, macOS and under Windows using MinGW 5.3.0 Qt 5.10.1 32bit. So, it seems it only affects MSVC. Something interesting is that if instead of linking at compile time I do load the library at runtime using
LoadLibrary
, the destructor is properly called. I imagine this is because theFreeLibrary
for my shared library is called automagically (and thus, the destructor of my global variable) before something else happens which causes the app to exit not gracefully.Is there anything I'm missing or is it a bug somehow? Thanks a lot beforehand.
-
@pamarcos said in Destructor of global variable in shared lib not called after QAudioDeviceInfo::availableDevices(QAudio::AudioOutput) or sending an HTTP(s) request:
I expect the destructor to be called when the library is unloaded when exiting the application.
That's correct, except it happens after you return from
main()
. Break it in the debugger to be sure if it's called, don't rely on text messages here. Qt may free theqDebug
stream just beforeQApplication::exec
returns (rather unlikely), or the debug stream global may be destroyed before yours (much more likely). -
@kshegunov said in Destructor of global variable in shared lib not called after QAudioDeviceInfo::availableDevices(QAudio::AudioOutput) or sending an HTTP(s) request:
Break it in the debugger to be sure if it's called, don't rely on text messages here.
Yes, I already tried that and the breakpoint is not hit. I also printed using
std::cout
, showed a popup using Windows API... same result. The destructor doesn't seem to be called at all. -
@pamarcos said in Destructor of global variable in shared lib not called after QAudioDeviceInfo::availableDevices(QAudio::AudioOutput) or sending an HTTP(s) request:
The destructor doesn't seem to be called at all.
That's quite odd indeed. You may want to try Q_GLOBAL_STATIC and see if that makes a difference, but the loader should call your destructor nonetheless. It may be some peculiarity of the compiler, so you may want to try MinGW to compare?
-
@kshegunov said in Destructor of global variable in shared lib not called after QAudioDeviceInfo::availableDevices(QAudio::AudioOutput) or sending an HTTP(s) request:
That's quite odd indeed. You may want to try Q_GLOBAL_STATIC and see if that makes a difference, but the loader should call your destructor nonetheless. It may be some peculiarity of the compiler, so you may want to try MinGW to compare?
Thanks for the suggestion. Using
Q_GLOBAL_STATIC
makes no difference. However, with MinGW 5.3.0 5.10.1 32bit the destructor gets called as it should. Unfortunately, I can't use MinGW since the whole project relies in MSVC, plus Visual Leak Detector only works with MSVC and GCC's address sanitizer does not support Windows AFAIK.I will update the original description to provide with the new information gathered.
-
I have just opened a bug report regarding this: https://bugreports.qt.io/browse/QTBUG-67353