From 5641d4539e60a09e8b85e82605f902d78bbdeae9 Mon Sep 17 00:00:00 2001 From: Murray Read Date: Fri, 17 Feb 2012 13:53:49 +0000 Subject: RR scheduler error handling for deleted active objects We have discovered that the active object ConnectionStarter could potentially leave after deleteing itself in RunL. If that were to happen, QtRRActiveScheduler::RunMarkedIfReady would have crashed when it asked the deleted active object to handle the error. Some active object deletion detection has been added to QtRRActiveScheduler::RunMarkedIfReady to protect against crashes. The ConnectionStarter active object has been modified so that even if it does leave, when running in CActiveScheduler, it still won't cause a crash and will clean itself up correctly. Task-number: ou1cimx1#979241 Change-Id: Iafa10b96bbd8bedfec82d6d546c7ffaf0557fd8b Reviewed-by: Shane Kearns --- src/corelib/kernel/qeventdispatcher_symbian.cpp | 8 ++++++-- src/plugins/bearer/symbian/qnetworksession_impl.cpp | 6 ++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp index 5d7c59c..f209b7a 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian.cpp +++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp @@ -843,8 +843,12 @@ QtRRActiveScheduler::RunResult QtRRActiveScheduler::RunMarkedIfReady(TInt &runPr dataAccess->iStatus.iFlags&=~TRequestStatusAccess::ERequestActiveFlags; int vptr = *(int*)active; // vptr can be used to identify type when debugging leaves TRAP(error, QT_TRYCATCH_LEAVING(active->RunL())); - if (error!=KErrNone) - error=active->RunError(error); + if (error!=KErrNone) { + if (vptr != *(int*)active) + qWarning("Active object vptr change from 0x%08x to 0x%08x. Error %i not handled.", vptr, *(int*)active, error); + else + error=active->RunError(error); + } if (error) { qWarning("Active object (ptr=0x%08x, vptr=0x%08x) leave: %i\n", active, vptr, error); dispatcher->activeObjectError(error); diff --git a/src/plugins/bearer/symbian/qnetworksession_impl.cpp b/src/plugins/bearer/symbian/qnetworksession_impl.cpp index 9f6d08d..fbf21fa 100644 --- a/src/plugins/bearer/symbian/qnetworksession_impl.cpp +++ b/src/plugins/bearer/symbian/qnetworksession_impl.cpp @@ -1050,7 +1050,7 @@ void QNetworkSessionPrivateImpl::ConnectionStartComplete(TInt statusCode) qDebug() << "QNS this : " << QString::number((uint)this) << " - " << "RConnection::Start completed with status code: " << statusCode; #endif - delete ipConnectionStarter; + // ConnectionStarter *ipConnectionStarter will delete itself at the end of RunL ipConnectionStarter = 0; switch (statusCode) { @@ -1572,12 +1572,14 @@ void ConnectionStarter::Start(TConnPref &pref) void ConnectionStarter::RunL() { iOwner.ConnectionStartComplete(iStatus.Int()); - //note owner deletes on callback + delete this; } TInt ConnectionStarter::RunError(TInt err) { qWarning() << "ConnectionStarter::RunError" << err; + // there must have been a leave from iOwner.ConnectionStartComplete, in which case "delete this" in RunL was missed. + delete this; return KErrNone; } -- cgit v0.12