04-09-2013 11:05 AM
I just released an app called Go Music and it streams music from a user's Google Music library to their phone. Every so often when I download the music stream I get this error:
SignalKill() at 0x1ad20c4 raise() at 0x1ac25a4 __malloc_panic_str() at 0x1abd0f4 _list_release() at 0x1abed48 __free() at 0x1ac012c 0x78869934 0x78869934
At the point where I do:
Anyone else experience this with QNetworkReply? It doesn't always happen but it happens often enough to be a major bug in my app.
Solved! Go to Solution.
04-09-2013 11:11 AM
04-09-2013 11:12 AM
Have you checked for any network request errors before you tried to read the reply?
if(mReply->error() == QNetworkReply::NoError)
04-09-2013 11:15 AM
I've been using this class all the time and it's very stable. If you could post the code where it's being created and used maybe we'll spot something.
A wild guess: how do you delete QNetworkReply instances? They should be deleted In finished() signal handler using deleteLater().
I do have it doing a deleteLater() but there is a QNetworkReply instance that I don't delete but keep reusing. Should I call close() on it?
04-09-2013 11:18 AM
04-09-2013 11:27 AM
Do not reuse it after connection is closed, just deleteLater() it after a call to readAll. It will be closed automatically. QNetworkManager's methods such as post() return a new QNetworkReply instance every time.
The reason I reuse it is because if in the middle of a song download the user goes to the next song, I want to abort the currentReply, so I retain the currentReply pointer in the case that I need to do that. I guess I should instead connect the signals to the abort() slot instead.
04-09-2013 11:38 AM
04-09-2013 12:49 PM
If you store currentReply in a member variable then it should be safe to reference it until deleteLater() is called. After a call to deleteLater you can NULL it and check if the variable is not-NULL when referencing it in other functions.
Attaching a signal directly to QNetworkReply's abort() slot will probably also work, but the reply has to be deleted as well.
I suppose finished() signal will still be emitted after a call to abort() and the reply can be deleted in finished() as usual, but I'm not sure about this.
I'm testing it now with the abort stuff hooked up, see if I can get it to crash.
04-09-2013 01:37 PM - edited 04-09-2013 01:39 PM
Ok, after testing for a while I am getting this now:
SignalKill() at 0x14320c4 raise() at 0x14225a4 __malloc_panic_str() at 0x141d0f4 _list_release() at 0x141ed48 __free() at 0x142012c 0x78b7f042 QCoreApplicationPrivate::sendPostedEvents() at 0x78b7dd12 QEventDispatcherUNIX::processEvents() at 0x78b9d608 QEventLoop::processEvents() at 0x78b7a69a QEventLoop::exec() at 0x78b7a85c
and this is right as I do this:
qDebug() << "GMA: Complete Bytes"; QByteArray arr(reply->readAll()); qDebug() << "GMA: Made it localized"; emit complete(arr);
The last think I see in slog2info is Complete Bytes.
04-09-2013 01:39 PM - edited 04-09-2013 01:54 PM
Please post the complete code.
I've looked at the code but unable to see how it is supposed to work.
From my understanding the logic should be similar to this one:
1. Initialize networkReply member variable to NULL in constructor.
2. When request should be initiated, call QNetworkAccessManager's post() method. It returns a QNetworkReply instance. Connect onFinished() slot to finished() signal of QNetworkReply. Store QNetworkReply in a member variable.
3. If user decided to stop the transfer, check if networkReply member variable is not NULL and call networkReply->stop() if it isn't. Do NOT destroy the reply yet.
4. In onFinished() slot check if any errors occured and if there is no errors, call readAll() and process the data. If there were errors do nothing. In both cases call deleteLater() on reply and set networkReply member variable to NULL. Do not call close() in onFinished(), it will be done automatically.