Solved Shutting down QMLApplicationEngine
-
I have a Qt desktop program with multiple threads and with a qmlApplicationEngine running in the main thread. I am having trouble shutting down the application without getting a segmentation fault. The debugger says the segfault is a double free or corruption. I have put print statements in all of my objects and threads to verify that I am shutting them down in the desired order. If I shut down the program without actively deleting the qmlApplicationEngine, then I don't get any errors but I have to manually close the application window and then the program crashes.
If I close down the qml application engine using deleteLater() I get the segmenation fault. I have also tried using quit() and then connecting quit() to deleteLater() which gives me the same error.
I am wondering if there is a standard process for shutting down a QmlApplicationEngine that is on the heap.
I make sure to delete child objects before their parents and I do not try to manually delete anything on the stack. I have also made sure that I do delete all objects on the heap. Even further, I don't get the segmentation fault when I leave the qmlApplicationEngine running but then the app obviously doesn't close and you have to manually close the qml window and force the program to end. This error only occurs when I try to get the whole application to shut down smoothly without the user force closing the qml window.
The code I use to shut delete everything in my main thread depends on a serial thread being done at which point all objects on the heap are deleted except for my qmlApplicationEngine called map.
QObject::connect(serialThread, SIGNAL(finished()), serialThread, SLOT(deleteLater()));
QObject::connect(serialThread, SIGNAL(serialThreadDone()), waypoint, SLOT(deleteLater()));
QObject::connect(serialThread, SIGNAL(serialThreadDone()), tempCoord, SLOT(deleteLater()));
QObject::connect(serialThread, SIGNAL(serialThreadDone()), home, SLOT(deleteLater()));
QObject::connect(serialThread, SIGNAL(serialThreadDone()), quitButton, SLOT(deleteLater()));
QObject::connect(serialThread, SIGNAL(finished()), map, SLOT(deleteLater()));Thanks!
-
@ellend Do any of these objects have a parent? If so then you most probably delete them twice.
For example I'm wondering why you delete a button explicitly:QObject::connect(serialThread, SIGNAL(serialThreadDone()), quitButton, SLOT(deleteLater()));
Does this button have a parent?
-
@jsulm Sorry for the confusion, quit button is not actually a button, it's a c++ class that handles user input through certain buttons and sends out serial messages accordingly. As far as i know none of these objects have parents, they are instantiations of c++ classes that inherit qObject so that I can expose them to qml and access their information in the qmlApplicationEngine.
Any objects that I dynamically allocate are deleted in the same thread where they were created and are deleted children before parents. It is only when I add the deletion of the qmlApplicationEngine that I get the double free/corruption error. I am wondering if somehow one of these objects has become a child of the application engine? Is that possible? I never explicitly assign any of them parents because they aren't intended to be used like a widget, layout, etc. They just have to inherit QObject so that I can use access them from the qml engine.
-
This post is deleted! -
ok I have tested a few more things and think that the only reason that deleting the qmlApplicationEngine causes the crash is because it ends the last process in the main thread and the thread returns. I tried instantiating the qmlEnging on the stack so that qt would take care of its deletion. When the user tells the program to quit it still shuts down all but the main thread, deletes objects in the thread where they were created, and leaves everything on the stack to be handled by qt. All communication and gui processes stop, and then you have to close the qmlEngine manually with the x in the top left corner at which point the program ends and crashes with the same error.
Another note - the error message itself actually changes between "munmap_chunk() : invalid pointer, free() : invalid size, and double free or corruption" i have managed to get all three messages with the same code.
-
@ellend Objects allocated on the stack are not managed by Qt - this is how C/C++ and most other programming languages handle stack allocated memory.
Without code I have no idea where the error is, but it seems that you're deleting something which is already deleted by Qt (an object with parent). -
I have solved my problem by using a dynamically linked executable instead of statically linked. I couldn't figure out what code to show you because I understand how the stack and heap objects are dealt with and couldn't find anything wrong with what I was doing. When I dynamically link the executable and run it I get a perfect shutdown with an exit code of 0. I have had numerous problems trying to statically link qt executables and have no idea if it has to do with ubuntu 16.04 or Qt5.9. Either way that seemed to solve my problem.