abort reply crashes with access violation

3

I have a huge problem and I actaully thought that I solved it. I have an application that uses the QNetworkAccessManager. This QNAM is located in a class. When I perform requests on this QNAM all of them are done in a wrapper which holds the reply and does retry logic on it

For example if I have a putBlob (which inherits from baseRequest) in the constructor I pass a reference to the QNAM. I den perform the request on it and save a pointer to the reply. The reply will then be the wrappers child so the QNAM no longer has ownership over it. The wrappers are children of the original class which holds the QNAM.

class has a QNAM, and children "putBlobRequest", which has child "QNetworkReply*"

The issue now is when the user wants to cancel which should delete the main object and everything in it. The wrappers should also abort its QNetworkReply and disconnect (so that it doesnt call finish())

my destructor on the baseRequest (which holds the QNetworkReply and is its parent) looks like this:

if(_reply) {
    if(_reply->isRunning()) {
        _reply->disconnect(SIGNAL(finished()));
        _reply->disconnect(SIGNAL(uploadProgress(qint64, qint64)));
        _reply->abort();
    }
}

The delete is done when the wrapper gets killed in the class that holds it.( right?)

This works sometimes, but sometimes I get a huge access violation and everything crashes with the following callstack:

QtCored4.dll!QObject::disconnect(const QObject * sender, const char * signal, const QObject * receiver, const char * method)  Line 2891 + 0x8 bytes C++
QtNetworkd4.dll!QNetworkReplyImpl::abort()  Line 874 + 0x18 bytes   C++
FrameworkAzure.dll!BaseRequest::~BaseRequest()  Line 129 + 0xa bytes    C++
FrameworkAzure.dll!PutBlobRequest::~PutBlobRequest()  Line 24 + 0x5e bytes  C++
FrameworkAzure.dll!PutBlobRequest::`scalar deleting destructor'()  + 0xb bytes  C++
FrameworkAzure.dll!AzureBlobStorageProvider::~AzureBlobStorageProvider()  Line 41 + 0xa8 bytes  C++

So first the abort() gets called which calls the following:

if (d->outgoingData)
    disconnect(d->outgoingData, 0, this, 0); <--- we go in here

Which takes me to line 2891 in QOBject.cpp here:

const QMetaObject *smeta = sender->metaObject(); 

where it crashes with the error:

Unhandled exception at 0x66c2c490 (QtCored4.dll) in CloudSync.exe: 0xC0000005: Access violation reading location 0xdddddddd.

The adress "0xdddddddd" is the "sender".

Why is the sender object not readable? What am I doing wrong? Please help!

EDIT:

Also tried:

if(_reply) {
    if(_reply->isRunning()) {
        disconnect(_reply, SIGNAL(finished()), this, SLOT(handleFinishedRequest()));
        _reply->abort();

    }
}

where I also disconnect the uploadProgress in the dervied putBlob. Also tried without the disconnect but with the same issue that the "sender" is violated

c++
qt
access-violation
qnetworkaccessmanager
asked on Stack Overflow May 3, 2012 by chikuba • edited May 4, 2012 by chikuba

1 Answer

0

In my case, I have a function of replyFinished as below:

void MyClass::replyFinished(QNetworkReply *reply)
{
   ...
   delete reply;
}

In my program, this function is connected via QNetworkAccessManager, thus the reply won't disconnect with it even I have called disconnect(reply, ...). Command abort will trigger this function (replyFinished) and delete the reply, I delete it one more time (via reply->deleteLater()) and lead crashing.

Solution: add a property to reply and check them.

disconnect(reply, nullptr, this, nullptr);
reply->setProperty("deleting", 1);
reply->abort();
...
void MyClass::replyFinished(QNetworkReply *reply)
{
   if (reply->property("deleting").isValid())
      return;

   ...
   delete reply;
}
answered on Stack Overflow Jan 15, 2020 by Tony

User contributions licensed under CC BY-SA 3.0