From 264c64380978d7b0bd3ecb56a861eb004cc58b01 Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Thu, 3 May 2018 17:45:51 +0200 Subject: wallet: Reset BerkeleyDB handle after connection fails According to the BerkeleyDB docs, the DbEnv handle may not be accessed after close() has been called. This change ensures that we create a new handle after close() is called. This avoids a segfault when the first connection attempt fails and then a second connection attempt tries to call open() on the already closed DbEnv handle. --- src/wallet/db.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index 10a06e4b9a..adf6944280 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -169,6 +169,7 @@ bool BerkeleyEnvironment::Open(bool retry) S_IRUSR | S_IWUSR); if (ret != 0) { dbenv->close(0); + Reset(); LogPrintf("BerkeleyEnvironment::Open: Error %d opening database environment: %s\n", ret, DbEnv::strerror(ret)); if (retry) { // try moving the database env out of the way -- cgit v1.2.3 From b6f0b4d8595df0241a6499cd57e7ddac56558bf1 Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Wed, 9 May 2018 00:20:12 +0200 Subject: wallet: Improve logging when BerkeleyDB environment fails to close --- src/wallet/db.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index adf6944280..7e75ee7ad1 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -102,7 +102,7 @@ void BerkeleyEnvironment::Close() int ret = dbenv->close(0); if (ret != 0) - LogPrintf("BerkeleyEnvironment::EnvShutdown: Error %d shutting down database environment: %s\n", ret, DbEnv::strerror(ret)); + LogPrintf("BerkeleyEnvironment::Close: Error %d closing database environment: %s\n", ret, DbEnv::strerror(ret)); if (!fMockDb) DbEnv((u_int32_t)0).remove(strPath.c_str(), 0); } @@ -168,9 +168,12 @@ bool BerkeleyEnvironment::Open(bool retry) nEnvFlags, S_IRUSR | S_IWUSR); if (ret != 0) { - dbenv->close(0); - Reset(); LogPrintf("BerkeleyEnvironment::Open: Error %d opening database environment: %s\n", ret, DbEnv::strerror(ret)); + int ret2 = dbenv->close(0); + if (ret2 != 0) { + LogPrintf("BerkeleyEnvironment::Open: Error %d closing failed database environment: %s\n", ret2, DbEnv::strerror(ret2)); + } + Reset(); if (retry) { // try moving the database env out of the way fs::path pathDatabaseBak = pathIn / strprintf("database.%d.bak", GetTime()); -- cgit v1.2.3