QNetworkReply abort() crash

Lubomir I. Ivanov neolit123 at gmail.com
Fri Nov 29 08:17:54 UTC 2013


http://trac.hohndel.org/ticket/309

the crash is caused by the reply->deleteLater() call in:

SubsurfaceWebServices::buttonClicked()
QDialogButtonBox::RejectRole

here is something i've tried doing to solve the issues, to no avail:

- use only one instance of QNetworkAccessManager - this should work OK...
- do not use deleteLater(), i'm not sure why it's recommended since i
think it would be better to immediately delete like in this example:
http://developer.nokia.com/Community/Wiki/Creating_an_HTTP_network_request_in_Qt

otherwise aren't two sequential calls to deleteLater() creating a race?

- the reply->abort() call on cancel is crashing if a download is in
progress and i have no idea why is that:

#0  0x1218465b in QHash<QNetworkRequest::KnownHeaders, QVariant>::value (
    this=0x2561b774, akey=@0x289b3c)
    at ../../include/QtCore/../../src/corelib/tools/qhash.h:609
#1  0x120e6ffe in QNetworkReplyImplPrivate::finished (this=0x2561b6e0)
    at access/qnetworkreplyimpl.cpp:743
#2  0x120e7d89 in QNetworkReplyImpl::abort (this=0x23bd5648)
    at access/qnetworkreplyimpl.cpp:885
#3  0x00466c0b in SubsurfaceWebServices::buttonClicked (this=0x23c30658,
    button=0x232a2058) at qt-ui/subsurfacewebservices.cpp:101
#4  0x0047adb7 in WebServices::qt_static_metacall (_o=0x23c30658,

lubomir
--
-------------- next part --------------
diff --git a/qt-ui/subsurfacewebservices.cpp b/qt-ui/subsurfacewebservices.cpp
index 7ece0a6..a9f57ee 100644
--- a/qt-ui/subsurfacewebservices.cpp
+++ b/qt-ui/subsurfacewebservices.cpp
@@ -19,10 +19,19 @@ WebServices::WebServices(QWidget* parent, Qt::WindowFlags f): QDialog(parent, f)
 , reply(0)
 {
 	ui.setupUi(this);
+	manager = new QNetworkAccessManager(this);
 	connect(ui.buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(buttonClicked(QAbstractButton*)));
 	connect(ui.download, SIGNAL(clicked(bool)), this, SLOT(startDownload()));
 	ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
+}
 
+WebServices::~WebServices(void)
+{
+	if (reply) {
+		reply->abort();
+		delete reply;
+	}
+	delete manager;
 }
 
 void WebServices::hidePassword()
@@ -88,10 +97,11 @@ void SubsurfaceWebServices::buttonClicked(QAbstractButton* button)
 		}
 		break;
 		case QDialogButtonBox::RejectRole:
-			// we may want to clean up after ourselves, but this
-			// makes Subsurface throw a SIGSEGV...
-			// manager->deleteLater();
-			reply->deleteLater();
+			if (reply) {
+				reply->abort();
+				delete reply;
+				reply = NULL;
+			}
 			ui.progressBar->setMaximum(1);
 			break;
 		case QDialogButtonBox::HelpRole:
@@ -107,7 +117,6 @@ void SubsurfaceWebServices::startDownload()
 	QUrl url("http://api.hohndel.org/api/dive/get/");
 	url.setQueryItems( QList<QPair<QString,QString> >() << qMakePair(QString("login"), ui.userID->text()));
 
-	manager = new QNetworkAccessManager(this);
 	QNetworkRequest request;
 	request.setUrl(url);
 	request.setRawHeader("Accept", "text/xml");
@@ -135,8 +144,8 @@ void SubsurfaceWebServices::downloadFinished()
 	if (resultCode == DD_STATUS_OK){
 		ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(true);
 	}
-	manager->deleteLater();
-	reply->deleteLater();
+	delete reply;
+	reply = NULL;
 }
 
 void SubsurfaceWebServices::downloadError(QNetworkReply::NetworkError error)
@@ -144,8 +153,8 @@ void SubsurfaceWebServices::downloadError(QNetworkReply::NetworkError error)
 	ui.download->setEnabled(true);
 	ui.progressBar->setRange(0,1);
 	ui.status->setText(QString::number((int)QNetworkRequest::HttpStatusCodeAttribute));
-	manager->deleteLater();
-	reply->deleteLater();
+	delete reply;
+	reply = NULL;
 }
 
 void SubsurfaceWebServices::setStatusText(int status)
diff --git a/qt-ui/subsurfacewebservices.h b/qt-ui/subsurfacewebservices.h
index 515e3fe..3ed517a 100644
--- a/qt-ui/subsurfacewebservices.h
+++ b/qt-ui/subsurfacewebservices.h
@@ -14,6 +14,7 @@ class WebServices : public QDialog{
 	Q_OBJECT
 public:
     explicit WebServices(QWidget* parent = 0, Qt::WindowFlags f = 0);
+    ~WebServices(void);
 	void hidePassword();
 	void hideUpload();
 


More information about the subsurface mailing list