From cbfac2fdccc83b04d9c2027e9e21070d4ac7c7e5 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 1 May 2007 15:16:17 +0000 Subject: * Set a terminate() handler to ensure that we leave the BDB environment cleanly even when an exception is thrown from a destructor. We still crash, but we don't take all other Nix processes with us. --- src/libmain/shared.cc | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src/libmain/shared.cc') diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index 568c975c2978..ebdbeb11e114 100644 --- a/src/libmain/shared.cc +++ b/src/libmain/shared.cc @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -81,6 +82,23 @@ struct RemoveTempRoots void initDerivationsHelpers(); +static void closeStore() +{ + try { + throw; + } catch (std::exception & e) { + printMsg(lvlError, + format("FATAL: unexpected exception (closing store and aborting): %1%") % e.what()); + } + try { + store.reset((StoreAPI *) 0); + } catch (...) { + ignoreException(); + } + abort(); +} + + /* Initialize and reorder arguments, then call the actual argument processor. */ static void initAndRun(int argc, char * * argv) @@ -195,6 +213,12 @@ static void initAndRun(int argc, char * * argv) exit. */ RemoveTempRoots removeTempRoots; /* unused variable - don't remove */ + /* Make sure that the database gets closed properly, even if + terminate() is called (which happens sometimes due to bugs in + destructor/exceptions interaction, but that needn't preclude a + clean shutdown of the database). */ + std::set_terminate(closeStore); + run(remaining); /* Close the Nix database. */ -- cgit 1.4.1