Help fixing threading issues when running an application in (debug|release) mode in combination with shared libraries built vice versa
-
Hi,
Introduction
I have a set of shared libraries that I develop myself. I want to package them as release builds and build applications against those libraries. I want to be able to build my application either in debug mode or in release mode and have it run successfully.
However, when the build configuration of my application is different than that the libraries have been built with, I experience a crash (from QSqlDatabase, explaining below) and also see warnings about parents and children not belonging to the same thread.
Problematic combinations
Shared libraries build mode Application build mode Result debug debug excutes properly debug release crash and warnings release release executes properly release debug crash and warnings Further explanations
The described problems appear when I use Qt 5.12.7 with MinGW64 7.3 as well as with MSVC2017 on Windows.
I do not use QThread anywhere in my libraries nor in the application.
Neither the libraries nor the application contain any gui related code, be it widgets or qml.
The cause of the application segfault I see was easy to find: I am creating a QSqlDatabase and add it in my application. I then use the name of that database inside the shared libraries to access the connection via
QSqlDatabase::contains()
. To debug this, I printed what connections are present right after I add the database in the application and in subsequent calls from the libraries: WhereQSqlDatabase::connectionNames()
returns my connection both in the app and in the libraries when the build modes match, inside of the lib, it returns an empty list, when the build modes differ.The documentation states that the usage of
QSqlDatabase::contains()
andQSqlDatabase::connectionNames()
are thread safe, so I wonder why the output ofconnectionNames()
can even lead to different outputs from the application and from the library, even when I had different threads, which I still assume, I haven't.The other thing I see are warnings like
QObject: Cannot create children for a parent that is in a different thread. (Parent is xyz(0x12a06c90), parent's thread is QThread(0x129dc230), current thread is QThread(0x12923900)QObject::startTimer: Timers can only be used with threads started with QThread
Which also do not appear when the build modes match.
Questions
- How is it possible that there are such threading issues when I do not use QThread at all?
- Is it a wrong approach, to access a database that has been added to
QSqlDatabase
via its connection name? - How to make an application run in both debug and release mode, when I only ship the shared libraries built in release mode?
Thanks in advance for any help.
-
You're on windows, correct? Then you must not mix debug and release libraries at all. It may eat kittens otherwise.
-
Okay, thanks, I was not aware of that. I thought that the release libraries will work no matter whether I build the application which uses them in debug or release. So I have to ship both library sets and make the applications select the correct ones?
I am also building the same libs and apps for linux x86-64 and with an arm toolchain as well. Does that restriction in compatibility also apply for linux builds?
Thanks
-
You should not ship a debug version of your program. If you need debug symbols use release with debug information. You're also not allowed to distribute the debug msvcrt runtime libraries.
-
@devjb
Just to re-iterate what @Christian-Ehrlicher has just written: you are not allowed to ship MSVC Debug libraries, and it's not a good idea to do anyway, you must only distribute Release builds of all the the code/libraries you use. At which point, you are in the 3rd line of your table, everything is release, and your compatibility problem therefore goes away! -
Thanks for your input. It seems that there is need for further explanation.
First, I was not planning to ship MSVC libraries at all. Because not everybody has an MSVC environment available. I only use MSVC for the development of my libraries, because it builds ten times faster than MinGW. I only wanted to ship MinGW libraries.
However, you say it was not allowed to ship libs that are build with MSVC in debug mode. Then, just for my understanding, why can Qt do so with the framework? In the MSVC directory there are all the Qt5 libraries both as release and debug versions. Do they have a special agreement about this with Microsoft?
The other point is that the purpose of the set of shared libraries, which I build and ship is to enable others build their own applications against it.
If I do not provide the users with debug builds, they won't be able to run their own applications in debug mode at all. So they cannot debug their own code, can they?
Maybe I am missing a point here? With the statement by @Christian-Ehrlicher that it is not possible to do debug builds against release built shared libraries, I was about to make my build system produce both variants of libs, the debug builds with a
d
-suffix, so that users are able to debug their own applications. Basically the same like the Qt-Framework is shipped with.Why is this considered bad practice, where Qt does it with the framework the same way? Is there a different approach that will work as an alternative?
Furthermore, @Christian-Ehrlicher said in his first answer that you should not mix debug and release on Windows. Since I also make linux builds of the libraries, I still need to know if that means that this does not apply for linux.
Thanks again!
-
@devjb said in Help fixing threading issues when running an application in (debug|release) mode in combination with shared libraries built vice versa:
However, you say it was not allowed to ship libs that are build with MSVC in debug mode. Then, just for my understanding, why can Qt do so with the framework? In the MSVC directory there are all the Qt5 libraries both as release and debug versions.
This is wrong - maybe we were not clear. You are not allowed (by MS) to distributed to debug MSVC runtime dlls (msvcrtdXXX.dll and others) :)