Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
MC: lazily load the dwarf information
authorMartin Quinson <martin.quinson@ens-rennes.fr>
Sun, 14 Mar 2021 14:09:13 +0000 (15:09 +0100)
committerMartin Quinson <martin.quinson@ens-rennes.fr>
Sun, 14 Mar 2021 20:05:02 +0000 (21:05 +0100)
src/mc/inspect/ObjectInformation.cpp
src/mc/inspect/ObjectInformation.hpp
src/mc/inspect/mc_dwarf.cpp
src/mc/remote/RemoteProcess.cpp
teshsuite/mc/dwarf/dwarf.cpp

index e78ecc8..e94f255 100644 (file)
@@ -40,8 +40,10 @@ void* ObjectInformation::base_address() const
   return result;
 }
 
-Frame* ObjectInformation::find_function(const void* ip) const
+Frame* ObjectInformation::find_function(const void* ip)
 {
+  ensure_dwarf_loaded();
+
   /* This is implemented by binary search on a sorted array.
    *
    * We do quite a lot of those so we want this to be cache efficient.
@@ -64,8 +66,10 @@ Frame* ObjectInformation::find_function(const void* ip) const
              : nullptr;
 }
 
-const Variable* ObjectInformation::find_variable(const char* var_name) const
+const Variable* ObjectInformation::find_variable(const char* var_name)
 {
+  ensure_dwarf_loaded();
+
   auto pos = std::lower_bound(this->global_variables.begin(), this->global_variables.end(), var_name,
                               [](auto const& var, const char* name) { return var.name < name; });
   return (pos != this->global_variables.end() && pos->name == var_name) ? &(*pos) : nullptr;
index eb5e219..a9ed100 100644 (file)
@@ -48,7 +48,10 @@ struct FunctionIndexEntry {
  *  - etc.
  */
 class ObjectInformation {
+  bool dwarf_loaded = false; // Lazily loads the dwarf info
+
 public:
+  void ensure_dwarf_loaded(); // Used by functions that need the dwarf
   ObjectInformation() = default;
 
   // Not copiable:
@@ -123,13 +126,17 @@ public:
   void* base_address() const;
 
   /** Find a function by instruction address
+   *
+   *  Loads the dwarf information on need.
    *
    *  @param ip instruction address
    *  @return corresponding function (if any) or nullptr
    */
-  simgrid::mc::Frame* find_function(const void* ip) const;
+  simgrid::mc::Frame* find_function(const void* ip);
 
   /** Find a global variable by name
+   *
+   *  Loads the dwarf information on need.
    *
    *  This is used to ignore global variables and to find well-known variables
    *  (`__mmalloc_default_mdp`).
@@ -137,7 +144,7 @@ public:
    *  @param name scopes name of the global variable (`myproject::Foo::count`)
    *  @return corresponding variable (if any) or nullptr
    */
-  const simgrid::mc::Variable* find_variable(const char* name) const;
+  const simgrid::mc::Variable* find_variable(const char* name);
 
   /** Remove a global variable (in order to ignore it)
    *
index a11a069..d7b1868 100644 (file)
@@ -994,9 +994,7 @@ static void MC_load_dwarf(simgrid::mc::ObjectInformation* info)
   int fd = open(info->file_name.c_str(), O_RDONLY);
   xbt_assert(fd >= 0, "Could not open file %s", info->file_name.c_str());
   Elf* elf = elf_begin(fd, ELF_C_READ, nullptr);
-  xbt_assert(elf != nullptr, "Not an ELF file");
-  Elf_Kind kind = elf_kind(elf);
-  xbt_assert(kind == ELF_K_ELF, "Not an ELF file");
+  xbt_assert(elf != nullptr && elf_kind(elf) == ELF_K_ELF, "%s is not an ELF file", info->file_name.c_str());
 
   // Remember if this is a `ET_EXEC` (fixed location) or `ET_DYN`:
   Elf64_Half type = get_type(elf);
@@ -1147,18 +1145,26 @@ static void MC_post_process_types(simgrid::mc::ObjectInformation* info)
 namespace simgrid {
 namespace mc {
 
+void ObjectInformation::ensure_dwarf_loaded()
+{
+  if (dwarf_loaded)
+    return;
+  dwarf_loaded = true;
+
+  MC_load_dwarf(this);
+  MC_post_process_variables(this);
+  MC_post_process_types(this);
+  for (auto& entry : this->subprograms)
+    mc_post_process_scope(this, &entry.second);
+  MC_make_functions_index(this);
+}
+
 /** @brief Finds information about a given shared object/executable */
 std::shared_ptr<ObjectInformation> createObjectInformation(std::vector<xbt::VmMap> const& maps, const char* name)
 {
   auto result       = std::make_shared<ObjectInformation>();
   result->file_name = name;
   simgrid::mc::find_object_address(maps, result.get());
-  MC_load_dwarf(result.get());
-  MC_post_process_variables(result.get());
-  MC_post_process_types(result.get());
-  for (auto& entry : result.get()->subprograms)
-    mc_post_process_scope(result.get(), &entry.second);
-  MC_make_functions_index(result.get());
   return result;
 }
 
index 0899bd7..41cacdc 100644 (file)
@@ -357,10 +357,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 +422,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));
 }
 
index 78cff65..39739ca 100644 (file)
@@ -73,7 +73,7 @@ static void test_local_variable(simgrid::mc::ObjectInformation* info, const char
 }
 
 static const simgrid::mc::Variable* test_global_variable(const simgrid::mc::RemoteProcess& process,
-                                                         const simgrid::mc::ObjectInformation* info, const char* name,
+                                                         simgrid::mc::ObjectInformation* info, const char* name,
                                                          void* address, long byte_size)
 {
   const simgrid::mc::Variable* variable = info->find_variable(name);