Bug 915214 - Fix possible crash when shutting down the database connection in mozStorageConnection.cpp. r=Yoric a=gavin
authorPaolo Amadini <paolo.mozmail@amadzone.org>
Fri, 25 Oct 2013 19:31:51 +0200
changeset 160851 bc11f51b72482cce4ec6ea2a13893e7c55e14f14
parent 160850 ea44c93520abdf1d004c59c046f854df9dd93335
child 160852 2055faffc05d14360563a80f691ed569b87c611e
push id2961
push userlsblakk@mozilla.com
push dateMon, 28 Oct 2013 21:59:28 +0000
treeherdermozilla-beta@73ef4f13486f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersYoric, gavin
bugs915214
milestone26.0a2
Bug 915214 - Fix possible crash when shutting down the database connection in mozStorageConnection.cpp. r=Yoric a=gavin
storage/src/mozStorageConnection.cpp
--- a/storage/src/mozStorageConnection.cpp
+++ b/storage/src/mozStorageConnection.cpp
@@ -817,30 +817,35 @@ Connection::internalClose()
 #ifdef PR_LOGGING
   nsAutoCString leafName(":memory");
   if (mDatabaseFile)
       (void)mDatabaseFile->GetNativeLeafName(leafName);
   PR_LOG(gStorageLog, PR_LOG_NOTICE, ("Closing connection to '%s'",
                                       leafName.get()));
 #endif
 
+  // Set the property to null before closing the connection, otherwise the other
+  // functions in the module may try to use the connection after it is closed.
+  sqlite3 *dbConn = mDBConn;
+  mDBConn = nullptr;
+
   // At this stage, we may still have statements that need to be
   // finalized. Attempt to close the database connection. This will
   // always disconnect any virtual tables and cleanly finalize their
   // internal statements. Once this is done, closing may fail due to
   // unfinalized client statements, in which case we need to finalize
   // these statements and close again.
 
-  int srv = sqlite3_close(mDBConn);
+  int srv = sqlite3_close(dbConn);
 
   if (srv == SQLITE_BUSY) {
     // We still have non-finalized statements. Finalize them.
 
     sqlite3_stmt *stmt = NULL;
-    while ((stmt = ::sqlite3_next_stmt(mDBConn, stmt))) {
+    while ((stmt = ::sqlite3_next_stmt(dbConn, stmt))) {
       PR_LOG(gStorageLog, PR_LOG_NOTICE,
              ("Auto-finalizing SQL statement '%s' (%x)",
               ::sqlite3_sql(stmt),
               stmt));
 
 #ifdef DEBUG
       char *msg = ::PR_smprintf("SQL statement '%s' (%x) should have been finalized before closing the connection",
                                 ::sqlite3_sql(stmt),
@@ -864,27 +869,26 @@ Connection::internalClose()
       // Ensure that the loop continues properly, whether closing has succeeded
       // or not.
       if (srv == SQLITE_OK) {
         stmt = NULL;
       }
     }
 
     // Now that all statements have been finalized, we
-    // shoudl be able to close.
-    srv = ::sqlite3_close(mDBConn);
+    // should be able to close.
+    srv = ::sqlite3_close(dbConn);
 
   }
 
   if (srv != SQLITE_OK) {
     MOZ_ASSERT(srv == SQLITE_OK,
                "sqlite3_close failed. There are probably outstanding statements that are listed above!");
   }
 
-  mDBConn = nullptr;
   return convertResultCode(srv);
 }
 
 nsCString
 Connection::getFilename()
 {
   nsCString leafname(":memory:");
   if (mDatabaseFile) {