Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
help latest fedora with mc
[simgrid.git] / src / mc / remote / RemoteProcess.cpp
index 0b9b6e9..ddf1f30 100644 (file)
@@ -19,6 +19,7 @@
 #include <cerrno>
 #include <cstring>
 #include <memory>
+#include <mutex>
 #include <string>
 
 using simgrid::mc::remote;
@@ -34,6 +35,7 @@ namespace mc {
 static const std::vector<std::string> filtered_libraries = {
 #ifdef __linux__
     "ld",
+    "ld-linux-x86",
 #elif defined __FreeBSD__
     "ld-elf",
     "ld-elf32",
@@ -206,21 +208,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 +218,14 @@ 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(xbt_mheap_t mmalloc_default_mdp, unsigned long* maxpid, xbt_dynar_t actors,
+                         xbt_dynar_t dead_actors)
 {
+  this->heap_address      = remote(mmalloc_default_mdp);
+  this->maxpid_addr_      = remote(maxpid);
+  this->actors_addr_      = remote(actors);
+  this->dead_actors_addr_ = remote(dead_actors);
+
   this->memory_map_ = simgrid::xbt::get_memory_map(this->pid_);
   this->init_memory_map_info();
 
@@ -240,12 +233,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();
@@ -278,7 +265,7 @@ void RemoteProcess::refresh_heap()
   // Read/dereference/refresh the std_heap pointer:
   if (not this->heap)
     this->heap = std::make_unique<s_xbt_mheap_t>();
-  this->read_bytes(this->heap.get(), sizeof(mdesc), remote(this->heap_address));
+  this->read(this->heap.get(), this->heap_address);
   this->cache_flags_ |= RemoteProcess::cache_heap;
 }
 
@@ -305,15 +292,13 @@ void RemoteProcess::init_memory_map_info()
   XBT_DEBUG("Get debug information ...");
   this->maestro_stack_start_ = nullptr;
   this->maestro_stack_end_   = nullptr;
-  this->object_infos.resize(0);
+  this->object_infos.clear();
   this->binary_info = nullptr;
 
   std::vector<simgrid::xbt::VmMap> const& maps = this->memory_map_;
 
   const char* current_name = nullptr;
 
-  this->object_infos.clear();
-
   for (size_t i = 0; i < maps.size(); i++) {
     simgrid::xbt::VmMap const& reg = maps[i];
     const char* pathname           = maps[i].pathname.c_str();
@@ -459,8 +444,8 @@ std::string RemoteProcess::read_string(RemotePtr<char> address) const
 
 void* RemoteProcess::read_bytes(void* buffer, std::size_t size, RemotePtr<void> address, ReadOptions /*options*/) const
 {
-  if (pread_whole(this->memory_file, buffer, size, (size_t)address.address()) < 0)
-    xbt_die("Read at %p from process %lli failed", (void*)address.address(), (long long)this->pid_);
+  xbt_assert(pread_whole(this->memory_file, buffer, size, (size_t)address.address()) != -1,
+             "Read at %p from process %lli failed", (void*)address.address(), (long long)this->pid_);
   return buffer;
 }
 
@@ -472,13 +457,26 @@ void* RemoteProcess::read_bytes(void* buffer, std::size_t size, RemotePtr<void>
  */
 void RemoteProcess::write_bytes(const void* buffer, size_t len, RemotePtr<void> address) const
 {
-  if (pwrite_whole(this->memory_file, buffer, len, (size_t)address.address()) < 0)
-    xbt_die("Write to process %lli failed", (long long)this->pid_);
+  xbt_assert(pwrite_whole(this->memory_file, buffer, len, (size_t)address.address()) != -1,
+             "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);
@@ -569,32 +567,5 @@ void RemoteProcess::dump_stack() const
   _UPT_destroy(context);
   unw_destroy_addr_space(as);
 }
-
-unsigned long RemoteProcess::get_maxpid() const
-{
-  static const char* name = nullptr;
-  if (not name) {
-    name = "simgrid::kernel::actor::maxpid";
-    if (find_variable(name) == nullptr)
-      name = "maxpid"; // We seem to miss the namespaces when compiling with GCC
-  }
-  unsigned long maxpid;
-  read_variable(name, &maxpid, sizeof(maxpid));
-  return maxpid;
-}
-
-void RemoteProcess::get_actor_vectors(RemotePtr<s_xbt_dynar_t>& actors, RemotePtr<s_xbt_dynar_t>& dead_actors)
-{
-  static_assert(std::is_same<std::unique_ptr<simgrid::simix::Global>, decltype(simix_global)>::value,
-                "Unexpected type for simix_global");
-  static_assert(sizeof(simix_global) == sizeof(simgrid::simix::Global*), "Bad size for simix_global");
-
-  // TODO, avoid to reload `&simix_global`, `simix_global`, `*simix_global`
-  RemotePtr<simgrid::simix::Global> simix_global_p{this->read_variable<simgrid::simix::Global*>("simix_global")};
-  Remote<simgrid::simix::Global> simix_global = this->read<simgrid::simix::Global>(simix_global_p);
-
-  actors      = remote(simix_global.get_buffer()->actors_vector);
-  dead_actors = remote(simix_global.get_buffer()->dead_actors_vector);
-}
 } // namespace mc
 } // namespace simgrid