Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Move handle_waitpid from ModelChecker to RemoteProcessMemory
authorMartin Quinson <martin.quinson@ens-rennes.fr>
Sun, 19 Mar 2023 12:54:23 +0000 (13:54 +0100)
committerMartin Quinson <martin.quinson@ens-rennes.fr>
Sun, 19 Mar 2023 13:04:21 +0000 (14:04 +0100)
src/mc/ModelChecker.cpp
src/mc/ModelChecker.hpp
src/mc/remote/CheckerSide.cpp
src/mc/sosp/RemoteProcessMemory.cpp
src/mc/sosp/RemoteProcessMemory.hpp

index a9e0e99..71a7f08 100644 (file)
@@ -108,54 +108,4 @@ bool ModelChecker::handle_message(const char* buffer, ssize_t size)
   return true;
 }
 
-void ModelChecker::handle_waitpid(pid_t pid_to_wait)
-{
-  XBT_DEBUG("Check for wait event");
-  int status;
-  pid_t pid;
-  while ((pid = waitpid(-1, &status, WNOHANG)) != 0) {
-    if (pid == -1) {
-      if (errno == ECHILD) { // No more children:
-        xbt_assert(not this->get_remote_process_memory().running(), "Inconsistent state");
-        break;
-      } else {
-        XBT_ERROR("Could not wait for pid");
-        throw simgrid::xbt::errno_error();
-      }
-    }
-
-    if (pid == pid_to_wait) {
-      // From PTRACE_O_TRACEEXIT:
-#ifdef __linux__
-      if (status>>8 == (SIGTRAP | (PTRACE_EVENT_EXIT<<8))) {
-        unsigned long eventmsg;
-        xbt_assert(ptrace(PTRACE_GETEVENTMSG, pid_to_wait, 0, &eventmsg) != -1, "Could not get exit status");
-        status = static_cast<int>(eventmsg);
-        if (WIFSIGNALED(status))
-          Exploration::get_instance()->report_crash(status);
-      }
-#endif
-
-      // We don't care about non-lethal signals, just reinject them:
-      if (WIFSTOPPED(status)) {
-        XBT_DEBUG("Stopped with signal %i", (int) WSTOPSIG(status));
-        errno = 0;
-#ifdef __linux__
-        ptrace(PTRACE_CONT, pid_to_wait, 0, WSTOPSIG(status));
-#elif defined BSD
-        ptrace(PT_CONTINUE, pid_to_wait, (caddr_t)1, WSTOPSIG(status));
-#endif
-        xbt_assert(errno == 0, "Could not PTRACE_CONT");
-      }
-
-      else if (WIFSIGNALED(status)) {
-        Exploration::get_instance()->report_crash(status);
-      } else if (WIFEXITED(status)) {
-        XBT_DEBUG("Child process is over");
-        this->get_remote_process_memory().terminate();
-      }
-    }
-  }
-}
-
 } // namespace simgrid::mc
index 58654af..d75a38d 100644 (file)
@@ -27,7 +27,6 @@ public:
 
   RemoteProcessMemory& get_remote_process_memory() { return *remote_process_memory_; }
 
-  void handle_waitpid(pid_t pid_to_wait);                // FIXME move to RemoteApp
   bool handle_message(const char* buffer, ssize_t size); // FIXME move to RemoteApp
 };
 
index 9091592..eeaee22 100644 (file)
@@ -47,7 +47,7 @@ CheckerSide::CheckerSide(int sockfd, ModelChecker* mc) : channel_(sockfd)
         auto mc = static_cast<simgrid::mc::ModelChecker*>(arg);
         if (events == EV_SIGNAL) {
           if (sig == SIGCHLD)
-            mc->handle_waitpid(mc->get_remote_process_memory().pid());
+            mc->get_remote_process_memory().handle_waitpid();
           else
             xbt_die("Unexpected signal: %d", sig);
         } else {
index 2ebe51b..1973a93 100644 (file)
@@ -7,9 +7,11 @@
 
 #include "src/mc/sosp/RemoteProcessMemory.hpp"
 
+#include "src/mc/explo/Exploration.hpp"
 #include "src/mc/sosp/Snapshot.hpp"
 #include "xbt/file.hpp"
 #include "xbt/log.h"
+#include "xbt/system_error.hpp"
 
 #include <fcntl.h>
 #include <libunwind-ptrace.h>
@@ -22,6 +24,8 @@
 #include <mutex>
 #include <string>
 #include <string_view>
+#include <sys/ptrace.h>
+#include <sys/wait.h>
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_process, mc, "MC process information");
 
@@ -450,4 +454,55 @@ void RemoteProcessMemory::dump_stack() const
   _UPT_destroy(context);
   unw_destroy_addr_space(as);
 }
+
+void RemoteProcessMemory::handle_waitpid()
+{
+  XBT_DEBUG("Check for wait event");
+  int status;
+  pid_t pid;
+  while ((pid = waitpid(-1, &status, WNOHANG)) != 0) {
+    if (pid == -1) {
+      if (errno == ECHILD) { // No more children:
+        xbt_assert(not running(), "Inconsistent state");
+        break;
+      } else {
+        XBT_ERROR("Could not wait for pid");
+        throw simgrid::xbt::errno_error();
+      }
+    }
+
+    if (pid == this->pid()) {
+      // From PTRACE_O_TRACEEXIT:
+#ifdef __linux__
+      if (status >> 8 == (SIGTRAP | (PTRACE_EVENT_EXIT << 8))) {
+        unsigned long eventmsg;
+        xbt_assert(ptrace(PTRACE_GETEVENTMSG, pid, 0, &eventmsg) != -1, "Could not get exit status");
+        status = static_cast<int>(eventmsg);
+        if (WIFSIGNALED(status))
+          Exploration::get_instance()->report_crash(status);
+      }
+#endif
+
+      // We don't care about non-lethal signals, just reinject them:
+      if (WIFSTOPPED(status)) {
+        XBT_DEBUG("Stopped with signal %i", (int)WSTOPSIG(status));
+        errno = 0;
+#ifdef __linux__
+        ptrace(PTRACE_CONT, pid, 0, WSTOPSIG(status));
+#elif defined BSD
+        ptrace(PT_CONTINUE, pid, (caddr_t)1, WSTOPSIG(status));
+#endif
+        xbt_assert(errno == 0, "Could not PTRACE_CONT");
+      }
+
+      else if (WIFSIGNALED(status)) {
+        Exploration::get_instance()->report_crash(status);
+      } else if (WIFEXITED(status)) {
+        XBT_DEBUG("Child process is over");
+        terminate();
+      }
+    }
+  }
+}
+
 } // namespace simgrid::mc
index 51e477d..db53549 100644 (file)
@@ -59,6 +59,11 @@ public:
   RemoteProcessMemory& operator=(RemoteProcessMemory const&) = delete;
   RemoteProcessMemory& operator=(RemoteProcessMemory&&)      = delete;
 
+  pid_t pid() const { return pid_; }
+  bool running() const { return running_; }
+  void terminate() { running_ = false; }
+  void handle_waitpid();
+
   /* ************* */
   /* Low-level API */
   /* ************* */
@@ -114,17 +119,11 @@ public:
   std::vector<IgnoredRegion> const& ignored_regions() const { return ignored_regions_; }
   void ignore_region(std::uint64_t address, std::size_t size);
 
-  pid_t pid() const { return pid_; }
-
   bool in_maestro_stack(RemotePtr<void> p) const
   {
     return p >= this->maestro_stack_start_ && p < this->maestro_stack_end_;
   }
 
-  bool running() const { return running_; }
-
-  void terminate() { running_ = false; }
-
   void ignore_global_variable(const char* name) const
   {
     for (std::shared_ptr<ObjectInformation> const& info : this->object_infos)