+ XBT_LOG(prio, "Caused by an unknown exception");
+ }
+}
+
+static void show_backtrace(const simgrid::xbt::Backtrace& bt)
+{
+ if (simgrid::config::get_value<bool>("exception/cutpath")) {
+ XBT_CRITICAL("Display of current backtrace disabled by --cfg=exception/cutpath.");
+ return;
+ }
+ std::string res = bt.resolve();
+ XBT_CRITICAL("Current backtrace:");
+ XBT_CRITICAL(" -> %s", res.c_str());
+}
+
+static std::terminate_handler previous_terminate_handler = nullptr;
+
+static void handler()
+{
+ // Avoid doing crazy things if we get an uncaught exception inside an uncaught exception
+ static std::atomic_flag lock = ATOMIC_FLAG_INIT;
+ if (lock.test_and_set()) {
+ XBT_ERROR("Handling an exception raised an exception. Bailing out.");
+ std::abort();
+ }
+
+ // Get the current backtrace and exception
+ auto e = std::current_exception();
+ simgrid::xbt::Backtrace bt = simgrid::xbt::Backtrace();
+ try {
+ std::rethrow_exception(e);
+ }
+
+ // Parse error are handled differently, as the call stack does not matter, only the file location
+ catch (const simgrid::ParseError& e) {
+ XBT_ERROR("%s", e.what());
+ XBT_ERROR("Exiting now.");
+ std::abort();
+ }
+
+ // We manage C++ exception ourselves
+ catch (const std::exception& e) {
+ log_exception(xbt_log_priority_critical, "Uncaught exception", e);
+ show_backtrace(bt);
+ std::abort();
+ }
+
+ catch (const simgrid::ForcefulKillException&) {
+ XBT_ERROR("Received a ForcefulKillException at the top-level exception handler. Maybe a Java->C++ call that is not "
+ "protected in a try/catch?");
+ show_backtrace(bt);