Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
MC protocol: rename INITIAL_ADDRESSES msg to NEED_MEMINFO
[simgrid.git] / src / mc / remote / CheckerSide.cpp
index b680284..9d82879 100644 (file)
@@ -10,7 +10,6 @@
 #include "xbt/system_error.hpp"
 
 #ifdef __linux__
-#include <sys/personality.h>
 #include <sys/prctl.h>
 #endif
 
@@ -37,7 +36,7 @@ static simgrid::config::Flag<std::string> _sg_mc_setenv{
 
 namespace simgrid::mc {
 
-XBT_ATTRIB_NORETURN static void run_child_process(int socket, const std::vector<char*>& args)
+XBT_ATTRIB_NORETURN static void run_child_process(int socket, const std::vector<char*>& args, bool need_ptrace)
 {
   /* On startup, simix_global_init() calls simgrid::mc::Client::initialize(), which checks whether the MC_ENV_SOCKET_FD
    * env variable is set. If so, MC mode is assumed, and the client is setup from its side
@@ -49,12 +48,6 @@ XBT_ATTRIB_NORETURN static void run_child_process(int socket, const std::vector<
   sigemptyset(&mask);
   xbt_assert(sigprocmask(SIG_SETMASK, &mask, nullptr) >= 0, "Could not unblock signals");
   xbt_assert(prctl(PR_SET_PDEATHSIG, SIGHUP) == 0, "Could not PR_SET_PDEATHSIG");
-
-  // Make sure that the application process layout is not randomized, so that the info we gather is stable over re-execs
-  if (personality(ADDR_NO_RANDOMIZE) == -1) {
-    XBT_ERROR("Could not set the NO_RANDOMIZE personality");
-    throw xbt::errno_error();
-  }
 #endif
 
   // Remove CLOEXEC to pass the socket to the application
@@ -63,6 +56,8 @@ XBT_ATTRIB_NORETURN static void run_child_process(int socket, const std::vector<
              "Could not remove CLOEXEC for socket");
 
   setenv(MC_ENV_SOCKET_FD, std::to_string(socket).c_str(), 1);
+  if (need_ptrace)
+    setenv("MC_NEED_PTRACE", "1", 1);
 
   /* Setup the tokenizer that parses the cfg:model-check/setenv parameter */
   using Tokenizer = boost::tokenizer<boost::char_separator<char>>;
@@ -133,7 +128,7 @@ void CheckerSide::setup_events()
 
   socket_event_ = event_new(
       base, get_channel().get_socket(), EV_READ | EV_PERSIST,
-      [](evutil_socket_t sig, short events, void* arg) {
+      [](evutil_socket_t, short events, void* arg) {
         auto checker = static_cast<simgrid::mc::CheckerSide*>(arg);
         if (events == EV_READ) {
           std::array<char, MC_MESSAGE_LENGTH> buffer;
@@ -144,7 +139,9 @@ void CheckerSide::setup_events()
               throw simgrid::xbt::errno_error();
           }
 
-          if (not checker->handle_message(buffer.data(), size))
+          if (size == 0) // The app closed the socket. It must be dead by now.
+            checker->handle_waitpid();
+          else if (not checker->handle_message(buffer.data(), size))
             checker->break_loop();
         } else {
           xbt_die("Unexpected event");
@@ -170,7 +167,7 @@ void CheckerSide::setup_events()
   event_add(signal_event_, nullptr);
 }
 
-CheckerSide::CheckerSide(const std::vector<char*>& args, bool need_memory_introspection) : running_(true)
+CheckerSide::CheckerSide(const std::vector<char*>& args, bool need_memory_info) : running_(true)
 {
   // Create an AF_LOCAL socketpair used for exchanging messages between the model-checker process (ancestor)
   // and the application process (child)
@@ -182,7 +179,7 @@ CheckerSide::CheckerSide(const std::vector<char*>& args, bool need_memory_intros
 
   if (pid_ == 0) { // Child
     ::close(sockets[1]);
-    run_child_process(sockets[0], args);
+    run_child_process(sockets[0], args, need_memory_info); // We need ptrace if we need the mem info
     DIE_IMPOSSIBLE;
   }
 
@@ -191,16 +188,17 @@ CheckerSide::CheckerSide(const std::vector<char*>& args, bool need_memory_intros
   channel_.reset_socket(sockets[1]);
 
   setup_events();
-  wait_application_process(pid_);
+  if (need_memory_info)
+    wait_application_process(pid_);
 
   // Request the initial memory on need
-  if (need_memory_introspection) {
-    channel_.send(MessageType::INITIAL_ADDRESSES);
-    s_mc_message_initial_addresses_reply_t answer;
+  if (need_memory_info) {
+    channel_.send(MessageType::NEED_MEMINFO);
+    s_mc_message_need_meminfo_reply_t answer;
     ssize_t answer_size = channel_.receive(answer);
     xbt_assert(answer_size != -1, "Could not receive message");
-    xbt_assert(answer.type == MessageType::INITIAL_ADDRESSES_REPLY,
-               "The received message is not the INITIAL_ADDRESS_REPLY I was expecting but of type %s",
+    xbt_assert(answer.type == MessageType::NEED_MEMINFO_REPLY,
+               "The received message is not the NEED_MEMINFO_REPLY I was expecting but of type %s",
                to_c_str(answer.type));
     xbt_assert(answer_size == sizeof answer, "Broken message (size=%zd; expected %zu)", answer_size, sizeof answer);
 
@@ -217,14 +215,6 @@ CheckerSide::~CheckerSide()
   event_free(socket_event_);
   event_del(signal_event_);
   event_free(signal_event_);
-
-  if (running()) {
-    XBT_DEBUG("Killing process");
-    finalize(true);
-    kill(get_pid(), SIGKILL);
-    terminate();
-    handle_waitpid();
-  }
 }
 
 void CheckerSide::finalize(bool terminate_asap)
@@ -256,7 +246,7 @@ void CheckerSide::break_loop() const
 bool CheckerSide::handle_message(const char* buffer, ssize_t size)
 {
   s_mc_message_t base_message;
-  xbt_assert(size >= (ssize_t)sizeof(base_message), "Broken message");
+  xbt_assert(size >= (ssize_t)sizeof(base_message), "Broken message. Got only %ld bytes.", size);
   memcpy(&base_message, buffer, sizeof(base_message));
 
   switch (base_message.type) {
@@ -283,7 +273,7 @@ bool CheckerSide::handle_message(const char* buffer, ssize_t size)
         s_mc_message_ignore_memory_t message;
         xbt_assert(size == sizeof(message), "Broken message");
         memcpy(&message, buffer, sizeof(message));
-        get_remote_memory()->unignore_heap((void*)(std::uintptr_t)message.addr, message.size);
+        get_remote_memory()->unignore_heap((void*)message.addr, message.size);
       } else {
         XBT_INFO("Ignoring an UNIGNORE_HEAP message because we don't need to introspect memory.");
       }
@@ -366,8 +356,7 @@ void CheckerSide::handle_waitpid()
         xbt_assert(not this->running(), "Inconsistent state");
         break;
       } else {
-        XBT_ERROR("Could not wait for pid");
-        throw simgrid::xbt::errno_error();
+        xbt_die("Could not wait for pid: %s", strerror(errno));
       }
     }