Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
When an exception occures in kernel mode, display both kernel and actor stacks
authorMartin Quinson <martin.quinson@ens-rennes.fr>
Sat, 13 Feb 2021 21:13:37 +0000 (22:13 +0100)
committerMartin Quinson <martin.quinson@ens-rennes.fr>
Sat, 13 Feb 2021 21:17:11 +0000 (22:17 +0100)
- Also some cosmetics about the displayed backtraces: don't show the
  frames that are within our backtrace handling mechanism or below main.

.classpath
include/simgrid/Exception.hpp
src/kernel/actor/ActorImpl.cpp
src/xbt/backtrace.cpp
src/xbt/exception.cpp

index 7393058..32ea6c5 100644 (file)
@@ -5,7 +5,7 @@
                        <attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="simgrid/lib"/>
                </attributes>
        </classpathentry>
-       <classpathentry excluding="*/CMakeFiles/|CMakeFiles/" kind="src" path="examples/java"/>
+       <classpathentry excluding="*/CMakeFiles/|CMakeFiles/" kind="src" path="examples/deprecated/java"/>
        <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
        <classpathentry kind="output" path="bin"/>
 </classpath>
index 99834e3..5ccde00 100644 (file)
@@ -155,8 +155,12 @@ public:
 /** Exception raised when something is going wrong during the parsing of XML files */
 class ParseError : public Exception {
 public:
+  const std::string file_;
+  const int line_;
   ParseError(const std::string& file, int line, const std::string& msg)
       : Exception(XBT_THROW_POINT, xbt::string_printf("Parse error at %s:%d: %s", file.c_str(), line, msg.c_str()))
+      , file_(file)
+      , line_(line)
   {
   }
   ParseError(const ParseError&)     = default;
index 5d6ddc1..cb929b9 100644 (file)
@@ -318,7 +318,38 @@ void ActorImpl::yield()
     XBT_DEBUG("Wait, maestro left me an exception");
     std::exception_ptr exception = std::move(exception_);
     exception_                   = nullptr;
-    std::rethrow_exception(std::move(exception));
+    try {
+      std::rethrow_exception(std::move(exception));
+    } catch (const simgrid::Exception& e) {
+      if (dynamic_cast<const simgrid::TimeoutException*>(&e) != nullptr) {
+        std::throw_with_nested(simgrid::TimeoutException(XBT_THROW_POINT, "Timeout raised in kernel mode."));
+
+      } else if (dynamic_cast<const simgrid::HostFailureException*>(&e) != nullptr) {
+        std::throw_with_nested(simgrid::HostFailureException(XBT_THROW_POINT, "HostFailure raised in kernel mode."));
+
+      } else if (dynamic_cast<const simgrid::NetworkFailureException*>(&e) != nullptr) {
+        std::throw_with_nested(
+            simgrid::NetworkFailureException(XBT_THROW_POINT, "NetworkFailure raised in kernel mode."));
+
+      } else if (dynamic_cast<const simgrid::StorageFailureException*>(&e) != nullptr) {
+        std::throw_with_nested(
+            simgrid::StorageFailureException(XBT_THROW_POINT, "StorageFailure raised in kernel mode."));
+
+      } else if (dynamic_cast<const simgrid::VmFailureException*>(&e) != nullptr) {
+        std::throw_with_nested(simgrid::VmFailureException(XBT_THROW_POINT, "VmFailure raised in kernel mode."));
+
+      } else if (dynamic_cast<const simgrid::CancelException*>(&e) != nullptr) {
+        std::throw_with_nested(simgrid::CancelException(XBT_THROW_POINT, "Cancel raised in kernel mode."));
+
+      } else if (dynamic_cast<const simgrid::TracingError*>(&e) != nullptr) {
+        std::throw_with_nested(simgrid::TracingError(XBT_THROW_POINT, "Tracing error raised in kernel mode."));
+
+      } else if (dynamic_cast<const simgrid::ParseError*>(&e) != nullptr) {
+        auto pe = dynamic_cast<const simgrid::ParseError*>(&e);
+        std::throw_with_nested(simgrid::ParseError(pe->file_, pe->line_, "Parse error raised in kernel mode."));
+      }
+      THROW_IMPOSSIBLE;
+    }
   }
 
   if (SMPI_switch_data_segment && not finished_) {
index 693ef55..43defb3 100644 (file)
@@ -10,6 +10,7 @@
 #include <xbt/sysdep.h>
 #include <xbt/virtu.h>
 
+#include <boost/algorithm/string/predicate.hpp>
 #include <cstdio>
 #include <cstdlib>
 #include <sstream>
 #if HAVE_BOOST_STACKTRACE_BACKTRACE
 #define BOOST_STACKTRACE_USE_BACKTRACE
 #include <boost/stacktrace.hpp>
+#include <boost/stacktrace/detail/frame_decl.hpp>
 #elif HAVE_BOOST_STACKTRACE_ADDR2LINE
 #define BOOST_STACKTRACE_USE_ADDR2LINE
 #include <boost/stacktrace.hpp>
+#include <boost/stacktrace/detail/frame_decl.hpp>
 #endif
 
 /** @brief show the backtrace of the current point (lovely while debugging) */
@@ -57,7 +60,25 @@ public:
   std::string resolve() const
   {
     std::stringstream ss;
-    ss << st;
+
+    int frame_count = 0;
+    int state       = 0;
+
+    for (boost::stacktrace::frame frame : st) {
+      if (state == 1) {
+        if (boost::starts_with(frame.name(), "simgrid::xbt::MainFunction") ||
+            boost::starts_with(frame.name(), "simgrid::kernel::context::Context::operator()()"))
+          break;
+        ss << "  ->  " << frame_count++ << "# " << frame.name() << " at " << frame.source_file() << ":"
+           << frame.source_line() << std::endl;
+        if (frame.name() == "main")
+          break;
+      } else {
+        if (frame.name() == "simgrid::xbt::Backtrace::Backtrace()")
+          state = 1;
+      }
+    }
+
     return ss.str();
   }
 #else
index bccfd6d..54a0df5 100644 (file)
@@ -43,7 +43,7 @@ void log_exception(e_xbt_log_priority_t prio, const char* context, std::exceptio
       // Do we have a backtrace?
       if (not simgrid::config::get_value<bool>("exception/cutpath")) {
         auto backtrace = with_context->resolve_backtrace();
-        XBT_LOG(prio, "  -> %s", backtrace.c_str());
+        XBT_LOG(prio, "Backtrace:\n%s", backtrace.c_str());
       }
     } else {
       XBT_LOG(prio, "%s %s: %s", context, name.get(), exception.what());
@@ -73,8 +73,7 @@ static void show_backtrace(const simgrid::xbt::Backtrace& bt)
     return;
   }
   std::string res = bt.resolve();
-  XBT_CRITICAL("Current backtrace:");
-  XBT_CRITICAL("  -> %s", res.c_str());
+  XBT_CRITICAL("Current backtrace:\n%s", res.c_str());
 }
 
 static std::terminate_handler previous_terminate_handler = nullptr;