Deleting QTcpSocket cause app crash
-
Hey
This is an interesting one. I have a worker thread.
Worker thread has a MainA-QObject that has some children, one of which is QTcpSocket. All of them live inside the worker thread.
The Child gets added to MainA during creation as socket(MainA) or via setParent(MainA)When MainA object dies, all its children get to be deleted too... but here qt crashes on me somehow. It's not always, it's like 5% chance it crash and is very random. My MainA is a QSharedPointer<>, Here is the picture of log >
QList.cpp
QObject>
Error Exception: Exception 0xc0000005 encountered at address 0x7ffd84b3bd27: Access violation reading location 0xffffffffffffffff
It looks to me like extraData can be invalid & cause the core crash?
Given my complex thread logic... it may be a bit difficult to reproduce it.
I do quite few of >if (mSocketPtr) { QMetaObject::invokeMethod(this, [this]() { QMetaObject::invokeMethod(mSocketPtr, [this]() { mSocketPtr->setParent(this); }, Qt::QueuedConnection); }, Qt::QueuedConnection); }
When I'm creating/moving objects. Feels like this can happen when objects gets deleted before properly getting moved to correct parent or something?
-
@Dariusz said in Deleting QTcpSocket cause app crash:
if (mSocketPtr) { QMetaObject::invokeMethod(this, [this]() { QMetaObject::invokeMethod(mSocketPtr, [this]() { mSocketPtr->setParent(this); }, Qt::QueuedConnection); }, Qt::QueuedConnection); }
WTF?
Please provide a minimal, compilable example.
-
@Christian-Ehrlicher Yeah that part is a bit dramatic... but a bit needed in order for all to get made in the proper thread if its being made in some odd thread. Since parent object can be made in threadD but then assigned thread C for processing and in the same time socket can be made in thread X and then he has to be moved to correct thread C but that may be delayed due to queue etc :D It's banana I know. This is so that objects gets handled/made asap and then pushed to correct threads on next loop.
In any case, I figured it out! I think...
Essentially
From threadX a socket could die, and then notification gets emitted, the problem is that this may be handled by a different thread and since I had QSharedPointer handling the lifetime of an object... it could be deleted from any thread, some times not socket thread! So I Had to implement custom delete on my sharedPointer and callthis->deleteLater()
from that rather than having itdelete this;
... Oh that was fun :- )Pain to find this error with all the tread switching/etc. Crashed like 1% of the time sigh.
Seems to run now smoothly.
So for any1 interested, to delete qt object using shared pointer , reimplement destructor call on shared pointer and do
deleteLater()
in it. -
@Dariusz said in Deleting QTcpSocket cause app crash:
My MainA is a QSharedPointer<>, Here is the picture of log >
I hope you have create it like this
QSharedPointer<MainA>(new MainA(), &QObject::deleteLater);
It looks to me like extraData can be invalid & cause the core crash?
Given my complex thread logic... it may be a bit difficult to reproduce it.
I do quite few ofif (mSocketPtr) { QMetaObject::invokeMethod(this, [this]() { QMetaObject::invokeMethod(mSocketPtr, [this]() { mSocketPtr->setParent(this); }, Qt::QueuedConnection); }, Qt::QueuedConnection); }
I do not understand this!
If you want to change parent for a class instance, why do it so complicat?
Setting parent can only be done if children and parent in same thread, but it muss not be done in the work thread!
I would do it like this:if(mSocketPtr && mSocketPtr->parent() != this) { if(mSocketPtr->thread() != this->thread()) { QMetaObject::invokeMethod(mSocketPtr, [this]() { mSocketPtr->moveToThread(this->thread()); mSocketPtr->setParent(this); }); } else mSocketPtr->setParent(this); }