Index: /Evidence/Evidence.cc
===================================================================
--- /Evidence/Evidence.cc	(revision 164)
+++ /Evidence/Evidence.cc	(revision 165)
@@ -15,9 +15,10 @@
   - The static method ToString() converts the contents of a
     DIMInfo service into text
-	
+  - A terminate-handler is installed for catching unhandled C++ exceptions.
+  
   All memory allocated by the non-static methods will be freed by the
   class destructor.
   
-  Oliver Grimm, December 2009
+  Oliver Grimm, February 2009
  
 \********************************************************************/
@@ -51,6 +52,9 @@
   
   // Start server
-  static char Init[] = "Server started (" EVIDENCE_REVISION "  Compiled "__DATE__ __TIME__ ")";
-  Status = new DimService((string(Name) + "/Status").c_str(), (char *) "C", Init, sizeof(Init));
+  string Rev(EVIDENCE_REVISION);
+  Rev = Rev.substr(1, Rev.size()-3);
+  if (asprintf(&InitMsg, "Server started (%s, compiled %s)", Rev.c_str(),__TIMESTAMP__) == -1) InitMsg = NULL;
+  
+  Status = new DimService((string(Name) + "/Status").c_str(), (char *) "C", InitMsg, strlen(InitMsg)+1);
 
   start(Name);
@@ -61,4 +65,5 @@
 EvidenceServer::~EvidenceServer() {
 
+  free(InitMsg);
   State(INFO, "Server stopped");
   
@@ -182,13 +187,41 @@
 }
 
-// C++ exception handler
+// C++ exception handler (derived from gcc __verbose_terminate_handler())
 void EvidenceServer::Terminate() {
 
-  string Msg = string(ThisServer->Status->getName()) + ": Caught unhandled exception";
-
-  printf("%s\n", Msg.c_str());
-  DimClient::sendCommand("DColl/Log", Msg.c_str());
-  
-  abort();
+  static char Msg[STATUS_SIZE];
+  static bool Terminating = false;
+
+  if (Terminating) {
+	snprintf(Msg, sizeof(Msg), "%s: Terminate() called recursively, calling abort()", ThisServer->Status->getName());
+	printf("%s\n", Msg);
+	DimClient::sendCommandNB("DColl/Log", Msg);
+	abort();
+  }
+  else {
+	Terminating = true;
+
+	// Make sure there was an exception; terminate is also called for an
+	// attempt to rethrow when there is no suitable exception.
+	type_info *Type = abi::__cxa_current_exception_type();
+	if (Type != NULL) {
+	  int Status = -1;
+	  char *Demangled = NULL;
+
+	  Demangled = abi::__cxa_demangle(Type->name(), 0, 0, &Status);
+	  snprintf(Msg, sizeof(Msg), "%s: Terminate() called after throwing an instance of '%s'", ThisServer->Status->getName(), Status==0 ? Demangled : Type->name());
+	  free(Demangled);
+
+	  // If exception derived from std::exception, more information.
+	  try { __throw_exception_again; }
+	  catch (exception &E) {
+		snprintf(Msg+strlen(Msg), sizeof(Msg)-strlen(Msg), " (what(): %s)", E.what());	  
+	  }
+	  catch (...) { }
+	}
+	else snprintf(Msg, sizeof(Msg), "%s: Terminate() called without an active exception", ThisServer->Status->getName());
+  }
+
+  ThisServer->State(FATAL, Msg);
 }
 
Index: /Evidence/Evidence.h
===================================================================
--- /Evidence/Evidence.h	(revision 164)
+++ /Evidence/Evidence.h	(revision 165)
@@ -6,7 +6,8 @@
 #include <string>
 #include <errno.h>
+#include <vector>
 #include <exception>
-#include <vector>
- 
+#include <cxxabi.h>
+
 #include "dis.hxx"
 #include "dic.hxx"
@@ -28,4 +29,5 @@
 
     DimService *Status;
+	char *InitMsg;
 
     static void SignalHandler(int); // static for signal()
