My app queues a series of files to download, and downloads each one in sequence. That is, it calls QNetworkAccessManager::get(), checks for errors in onFinished(), and if there are none, saves the data to disk. There are problems with this overall approach -- as opposed to writing the data as it arrives -- in that if a given file is too large, it will fill up the memory on a mobile device and cause the OS to kill the app.

That's not what I am seeing here.

And in fact, I am only seeing this for a particular file on a particular device, which happens to be a Nexus 7 running Android 5.1. Works fine on every iOS device I've tried, and a Nexus 7 running Android 6.0.1. The file downloads just fine, and there are no errors. But when I try to call readAll() on my non-null instance of QNetworkReply:

Qt Code:
  1. F/libc (23481): Fatal signal 6 (SIGABRT), code -6 in tid 23524 (QtThread)
  2. I/DEBUG ( 182): pid: 23481, tid: 23524, name: QtThread >>> my.org.appname <<<
  3. E/lowmemorykiller( 176): Error writing /proc/23481/oom_score_adj; errno=22
  4. I/Zygote ( 195): Process 23481 exited due to signal (6)
  5. I/ActivityManager( 543): Process my.org.appname (pid 23481) has died
To copy to clipboard, switch view to plain text mode 

Similar topic: http://www.qtcentre.org/threads/6684...-readAll-error

The author resolved it, but the solution was apparently so self-evident that no details were given.

My function is as follows:

Qt Code:
  1. bool DownloadManager::saveToDisk(const QString &fileName, QIODevice *data) {
  2. QFile file(fileName);
  3. bool ok = file.open(QIODevice::WriteOnly);
  4. if (ok) {
  5. QByteArray stuff = data->readAll(); // BOOM!
  6. file.write(stuff);
  7. file.close();
  8. }
  9. else
  10. qDebug() << QString("DownloadManager::saveToDisk(%1) - Failed: %2").arg(fileName).arg(file.errorString());
  11. return ok;
  12. }
To copy to clipboard, switch view to plain text mode 

And here is the calling code:

Qt Code:
  1. void DownloadManager::onFinished() {
  2. const QUrl urlObj = m_reply->url();
  3. const QString url = urlObj.toString();
  4. const QNetworkReply::NetworkError err = m_reply->error();
  5. if (err) {
  6. qDebug() << QString("DownloadManager::onFinished(%1) - Error: %2").arg(url).arg(m_reply->errorString());
  7. emit failure(url, (err == QNetworkReply::OperationCanceledError ? CanceledByUser : Network));
  8. }
  9. else {
  10. const QString fileName = absoluteSaveFileName(urlObj);
  11. if (saveToDisk(fileName, m_reply))
  12. emit success(url, fileName);
  13. else {
  14. qDebug() << QString("DownloadManager::onFinished(%1) - Failed to save to '%2'").arg(url).arg(fileName);
  15. emit failure(url, FileIO);
  16. }
  17. }
  18. m_reply->deleteLater();
  19. if (m_queue.isEmpty())
  20. setIsDownloading(false);
  21. else {
  22. m_reply = m_manager.get(m_queue.takeFirst());
  23. Q_ASSERT_X(m_reply, "onFinished", "Null pointer to QNetworkReply!");
  24. #ifndef QT_NO_SSL
  25. connect(m_reply, SIGNAL(sslErrors(QList<QSslError>)), SLOT(sslErrors(QList<QSslError>)));
  26. #endif
  27. }
  28. }
To copy to clipboard, switch view to plain text mode 

The cited topic and error message certainly make this look like a threading issue, but I need a hand with understanding and resolving it. I should add that I'm using Qt Creator 4.2.2 based on Qt 5.8.0.

Thanks in advance.