Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Revert "Reduce dependency on ptrace."
authorArnaud Giersch <arnaud.giersch@univ-fcomte.fr>
Tue, 9 Jul 2019 15:28:34 +0000 (17:28 +0200)
committerArnaud Giersch <arnaud.giersch@univ-fcomte.fr>
Tue, 9 Jul 2019 15:28:34 +0000 (17:28 +0200)
This reverts commit 6ae5ae138e9dd397b95d9e7741a5b28f194705d0.

src/mc/ModelChecker.cpp
src/mc/remote/Client.cpp

index d60341e..4250bff 100644 (file)
@@ -14,6 +14,7 @@
 #include "xbt/automaton.hpp"
 #include "xbt/system_error.hpp"
 
+#include <sys/ptrace.h>
 #include <sys/wait.h>
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_ModelChecker, mc, "ModelChecker");
@@ -71,7 +72,7 @@ void ModelChecker::start()
   // The model-checked process SIGSTOP itself to signal it's ready:
   const pid_t pid = process_->pid();
 
-  pid_t res = waitpid(pid, &status, WUNTRACED | WAITPID_CHECKED_FLAGS);
+  pid_t res = waitpid(pid, &status, WAITPID_CHECKED_FLAGS);
   if (res < 0 || not WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP)
     xbt_die("Could not wait model-checked process");
 
@@ -82,8 +83,14 @@ void ModelChecker::start()
 
   setup_ignore();
 
-  if (kill(pid, SIGCONT) != 0)
-    throw simgrid::xbt::errno_error("Could not wake up the model-checked process");
+#ifdef __linux__
+  ptrace(PTRACE_SETOPTIONS, pid, nullptr, PTRACE_O_TRACEEXIT);
+  ptrace(PTRACE_CONT, pid, 0, 0);
+#elif defined BSD
+  ptrace(PT_CONTINUE, pid, (caddr_t)1, 0);
+#else
+# error "no ptrace equivalent coded for this platform"
+#endif
 }
 
 static const std::pair<const char*, const char*> ignored_local_variables[] = {
@@ -303,9 +310,36 @@ void ModelChecker::handle_waitpid()
     }
 
     if (pid == this->process().pid()) {
-      xbt_assert(WIFEXITED(status) || WIFSIGNALED(status));
-      XBT_DEBUG("Child process is over");
-      this->process().terminate();
+
+      // From PTRACE_O_TRACEEXIT:
+#ifdef __linux__
+      if (status>>8 == (SIGTRAP | (PTRACE_EVENT_EXIT<<8))) {
+        if (ptrace(PTRACE_GETEVENTMSG, this->process().pid(), 0, &status) == -1)
+          xbt_die("Could not get exit status");
+        if (WIFSIGNALED(status)) {
+          MC_report_crash(status);
+          mc_model_checker->exit(SIMGRID_MC_EXIT_PROGRAM_CRASH);
+        }
+      }
+#endif
+
+      // We don't care about signals, just reinject them:
+      if (WIFSTOPPED(status)) {
+        XBT_DEBUG("Stopped with signal %i", (int) WSTOPSIG(status));
+        errno = 0;
+#ifdef __linux__
+        ptrace(PTRACE_CONT, this->process().pid(), 0, WSTOPSIG(status));
+#elif defined BSD
+        ptrace(PT_CONTINUE, this->process().pid(), (caddr_t)1, WSTOPSIG(status));
+#endif
+        if (errno != 0)
+          xbt_die("Could not PTRACE_CONT");
+      }
+
+      else if (WIFEXITED(status) || WIFSIGNALED(status)) {
+        XBT_DEBUG("Child process is over");
+        this->process().terminate();
+      }
     }
   }
 }
index 4a9f0bf..4e77404 100644 (file)
@@ -6,10 +6,11 @@
 #include "src/mc/remote/Client.hpp"
 #include "src/internal_config.h"
 #include <simgrid/modelchecker.h>
-#include <xbt/system_error.hpp>
 
+#include <cerrno>
 #include <cstdlib>
 #include <cstring>
+#include <sys/ptrace.h>
 #include <sys/socket.h>
 #include <sys/types.h>
 
@@ -56,8 +57,16 @@ Client* Client::initialize()
   instance_.reset(new simgrid::mc::Client(fd));
 
   // Wait for the model-checker:
-  if (raise(SIGSTOP) != 0)
-    throw simgrid::xbt::errno_error("Could not wait for the model-checker");
+  errno = 0;
+#if defined __linux__
+  ptrace(PTRACE_TRACEME, 0, nullptr, nullptr);
+#elif defined BSD
+  ptrace(PT_TRACE_ME, 0, nullptr, 0);
+#else
+#error "no ptrace equivalent coded for this platform"
+#endif
+  if (errno != 0 || raise(SIGSTOP) != 0)
+    xbt_die("Could not wait for the model-checker (errno = %d: %s)", errno, strerror(errno));
 
   instance_->handle_messages();
   return instance_.get();