]> AND Public Git Repository - simgrid.git/blobdiff - src/mc/remote/RemoteProcess.cpp
Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[mc] Terminate crashing applications too.
[simgrid.git] / src / mc / remote / RemoteProcess.cpp
index 0899bd7069ce1dec913e6f304d783eda2f533bb7..64b83b5a92607ad41b1b6c299e0137925b18bd4b 100644 (file)
@@ -19,6 +19,7 @@
 #include <cerrno>
 #include <cstring>
 #include <memory>
+#include <mutex>
 #include <string>
 
 using simgrid::mc::remote;
@@ -206,21 +207,6 @@ static ssize_t pwrite_whole(int fd, const void* buf, size_t count, off_t offset)
   return real_count;
 }
 
-static pthread_once_t zero_buffer_flag = PTHREAD_ONCE_INIT;
-static const void* zero_buffer;
-static const size_t zero_buffer_size = 10 * 4096;
-
-static void zero_buffer_init()
-{
-  int fd = open("/dev/zero", O_RDONLY);
-  if (fd < 0)
-    xbt_die("Could not open /dev/zero");
-  zero_buffer = mmap(nullptr, zero_buffer_size, PROT_READ, MAP_SHARED, fd, 0);
-  if (zero_buffer == MAP_FAILED)
-    xbt_die("Could not map the zero buffer");
-  close(fd);
-}
-
 int open_vm(pid_t pid, int flags)
 {
   std::string buffer = "/proc/" + std::to_string(pid) + "/mem";
@@ -231,8 +217,13 @@ int open_vm(pid_t pid, int flags)
 
 RemoteProcess::RemoteProcess(pid_t pid) : AddressSpace(this), pid_(pid), running_(true) {}
 
-void RemoteProcess::init()
+void RemoteProcess::init(void* mmalloc_default_mdp, void* maxpid, void* actors, void* dead_actors)
 {
+  this->heap_address      = mmalloc_default_mdp;
+  this->maxpid_addr_      = maxpid;
+  this->actors_addr_      = actors;
+  this->dead_actors_addr_ = dead_actors;
+
   this->memory_map_ = simgrid::xbt::get_memory_map(this->pid_);
   this->init_memory_map_info();
 
@@ -240,12 +231,6 @@ void RemoteProcess::init()
   xbt_assert(fd >= 0, "Could not open file for process virtual address space");
   this->memory_file = fd;
 
-  // Read std_heap (is a struct mdesc*):
-  const simgrid::mc::Variable* std_heap_var = this->find_variable("__mmalloc_default_mdp");
-  xbt_assert(std_heap_var, "No heap information in the target process");
-  xbt_assert(std_heap_var->address, "No constant address for this variable");
-  this->read_bytes(&this->heap_address, sizeof(mdesc*), remote(std_heap_var->address));
-
   this->smx_actors_infos.clear();
   this->smx_dead_actors_infos.clear();
   this->unw_addr_space            = simgrid::mc::UnwindContext::createUnwindAddressSpace();
@@ -357,10 +342,6 @@ void RemoteProcess::init_memory_map_info()
       this->binary_info = info;
   }
 
-  // Resolve time (including across different objects):
-  for (auto const& object_info : this->object_infos)
-    postProcessObjectInformation(this, object_info.get());
-
   xbt_assert(this->maestro_stack_start_, "Did not find maestro_stack_start");
   xbt_assert(this->maestro_stack_end_, "Did not find maestro_stack_end");
 
@@ -426,9 +407,14 @@ void RemoteProcess::read_variable(const char* name, void* target, size_t size) c
   const simgrid::mc::Variable* var = this->find_variable(name);
   xbt_assert(var, "Variable %s not found", name);
   xbt_assert(var->address, "No simple location for this variable");
-  xbt_assert(var->type->full_type, "Partial type for %s, cannot check size", name);
-  xbt_assert((size_t)var->type->full_type->byte_size == size, "Unexpected size for %s (expected %zu, was %zu)", name,
-             size, (size_t)var->type->full_type->byte_size);
+
+  if (not var->type->full_type) // Try to resolve this type. The needed ObjectInfo was maybe (lazily) loaded recently
+    for (auto const& object_info : this->object_infos)
+      postProcessObjectInformation(this, object_info.get());
+  xbt_assert(var->type->full_type, "Partial type for %s (even after re-resolving types), cannot retrieve its size.",
+             name);
+  xbt_assert((size_t)var->type->full_type->byte_size == size, "Unexpected size for %s (expected %zu, received %zu).",
+             name, size, (size_t)var->type->full_type->byte_size);
   this->read_bytes(target, size, remote(var->address));
 }
 
@@ -475,9 +461,22 @@ void RemoteProcess::write_bytes(const void* buffer, size_t len, RemotePtr<void>
     xbt_die("Write to process %lli failed", (long long)this->pid_);
 }
 
+static void zero_buffer_init(const void** zero_buffer, size_t zero_buffer_size)
+{
+  int fd = open("/dev/zero", O_RDONLY);
+  xbt_assert(fd >= 0, "Could not open /dev/zero");
+  *zero_buffer = mmap(nullptr, zero_buffer_size, PROT_READ, MAP_SHARED, fd, 0);
+  xbt_assert(*zero_buffer != MAP_FAILED, "Could not map the zero buffer");
+  close(fd);
+}
+
 void RemoteProcess::clear_bytes(RemotePtr<void> address, size_t len) const
 {
-  pthread_once(&zero_buffer_flag, zero_buffer_init);
+  static constexpr size_t zero_buffer_size = 10 * 4096;
+  static const void* zero_buffer;
+  static std::once_flag zero_buffer_flag;
+
+  std::call_once(zero_buffer_flag, zero_buffer_init, &zero_buffer, zero_buffer_size);
   while (len) {
     size_t s = len > zero_buffer_size ? zero_buffer_size : len;
     this->write_bytes(zero_buffer, s, address);
@@ -568,5 +567,18 @@ void RemoteProcess::dump_stack() const
   _UPT_destroy(context);
   unw_destroy_addr_space(as);
 }
+
+unsigned long RemoteProcess::get_maxpid() const
+{
+  unsigned long maxpid;
+  this->read_bytes(&maxpid, sizeof(unsigned long), remote(maxpid_addr_));
+  return maxpid;
+}
+
+void RemoteProcess::get_actor_vectors(RemotePtr<s_xbt_dynar_t>& actors, RemotePtr<s_xbt_dynar_t>& dead_actors)
+{
+  actors      = remote(static_cast<s_xbt_dynar_t*>(actors_addr_));
+  dead_actors = remote(static_cast<s_xbt_dynar_t*>(dead_actors_addr_));
+}
 } // namespace mc
 } // namespace simgrid