about summary refs log tree commit diff
path: root/src/libmain/shared.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2007-05-01T15·16+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2007-05-01T15·16+0000
commitcbfac2fdccc83b04d9c2027e9e21070d4ac7c7e5 (patch)
tree9bff2f93fb123a3ad05bb3712e3d2a875c6da53b /src/libmain/shared.cc
parent644946feed146396c00c288337bad26428970aa4 (diff)
* 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.

Diffstat (limited to 'src/libmain/shared.cc')
-rw-r--r--src/libmain/shared.cc24
1 files changed, 24 insertions, 0 deletions
diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc
index 568c975c29..ebdbeb11e1 100644
--- a/src/libmain/shared.cc
+++ b/src/libmain/shared.cc
@@ -7,6 +7,7 @@
 
 #include <iostream>
 #include <cctype>
+#include <exception>
 
 #include <sys/stat.h>
 #include <unistd.h>
@@ -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. */