Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Kill duplicate function + typos.
[simgrid.git] / src / mc / inspect / mc_dwarf.cpp
index 646ecc1..c936038 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2021. The SimGrid Team. All rights reserved.          */
+/* Copyright (c) 2008-2022. The SimGrid Team. All rights reserved.          */
 
 /* This program is free software; you can redistribute it and/or modify it
  * under the terms of the license (GNU LGPL) which comes with this package. */
 #include "src/mc/inspect/Variable.hpp"
 #include "src/mc/inspect/mc_dwarf.hpp"
 #include "src/mc/mc_private.hpp"
-#include "src/mc/remote/RemoteSimulation.hpp"
+#include "src/mc/remote/RemoteProcess.hpp"
 
 #include <algorithm>
 #include <array>
+#include <cerrno>
 #include <cinttypes>
 #include <cstdint>
 #include <cstdlib>
+#include <cstring>
 #include <fcntl.h>
 #include <memory>
 #include <unordered_map>
@@ -30,8 +32,6 @@
 #include <elfutils/libdw.h>
 #include <elfutils/version.h>
 
-#include <boost/algorithm/string/predicate.hpp>
-
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_dwarf, mc, "DWARF processing");
 
 /** @brief The default DW_TAG_lower_bound for a given DW_AT_language.
@@ -224,23 +224,12 @@ static const char* MC_dwarf_attr_integrate_string(Dwarf_Die* die, int attribute)
     return dwarf_formstring(&attr);
 }
 
-static Dwarf_Off MC_dwarf_attr_dieoffset(Dwarf_Die* die, int attribute)
-{
-  Dwarf_Attribute attr;
-  if (dwarf_hasattr_integrate(die, attribute) == 0)
-    return 0;
-  dwarf_attr_integrate(die, attribute, &attr);
-  Dwarf_Die subtype_die;
-  xbt_assert(dwarf_formref_die(&attr, &subtype_die) != nullptr, "Could not find DIE");
-  return dwarf_dieoffset(&subtype_die);
-}
-
 static Dwarf_Off MC_dwarf_attr_integrate_dieoffset(Dwarf_Die* die, int attribute)
 {
   Dwarf_Attribute attr;
   if (dwarf_hasattr_integrate(die, attribute) == 0)
     return 0;
-  dwarf_attr_integrate(die, DW_AT_type, &attr);
+  dwarf_attr_integrate(die, attribute, &attr);
   Dwarf_Die subtype_die;
   xbt_assert(dwarf_formref_die(&attr, &subtype_die) != nullptr, "Could not find DIE");
   return dwarf_dieoffset(&subtype_die);
@@ -399,10 +388,10 @@ static void MC_dwarf_fill_member_location(const simgrid::mc::Type* type, simgrid
   xbt_assert(not dwarf_hasattr(child, DW_AT_data_bit_offset), "Can't groke DW_AT_data_bit_offset.");
 
   if (not dwarf_hasattr_integrate(child, DW_AT_data_member_location)) {
-    if (type->type == DW_TAG_union_type)
-      return;
-    xbt_die("Missing DW_AT_data_member_location field in DW_TAG_member %s of type <%" PRIx64 ">%s",
-            member->name.c_str(), (uint64_t)type->id, type->name.c_str());
+    xbt_assert(type->type == DW_TAG_union_type,
+               "Missing DW_AT_data_member_location field in DW_TAG_member %s of type <%" PRIx64 ">%s",
+               member->name.c_str(), (uint64_t)type->id, type->name.c_str());
+    return;
   }
 
   Dwarf_Attribute attr;
@@ -473,8 +462,7 @@ static void MC_dwarf_add_members(const simgrid::mc::ObjectInformation* /*info*/,
         member.name = name;
       // Those base names are used by GCC and clang for virtual table pointers
       // respectively ("__vptr$ClassName", "__vptr.ClassName"):
-      if (boost::algorithm::starts_with(member.name, "__vptr$") ||
-          boost::algorithm::starts_with(member.name, "__vptr."))
+      if (member.name.rfind("__vptr$", 0) == 0 || member.name.rfind("__vptr.", 0) == 0)
         member.flags |= simgrid::mc::Member::VIRTUAL_POINTER_FLAG;
       // A cleaner solution would be to check against the type:
       // ---
@@ -742,7 +730,7 @@ static void MC_dwarf_handle_scope_die(simgrid::mc::ObjectInformation* info, Dwar
       frame.name = name;
   }
 
-  frame.abstract_origin_id = MC_dwarf_attr_dieoffset(die, DW_AT_abstract_origin);
+  frame.abstract_origin_id = MC_dwarf_attr_integrate_dieoffset(die, DW_AT_abstract_origin);
 
   // This is the base address for DWARF addresses.
   // Relocated addresses are offset from this base address.
@@ -963,7 +951,7 @@ static constexpr auto debug_paths = {
  */
 // Example:
 // /usr/lib/debug/.build-id/0b/dc77f1c29aea2b14ff5acd9a19ab3175ffdeae.debug
-static std::string find_by_build_id(std::vector<char> id)
+static int find_by_build_id(std::vector<char> id)
 {
   std::string filename;
   std::string hex = to_hex(id);
@@ -972,18 +960,20 @@ static std::string find_by_build_id(std::vector<char> id)
     filename = std::string(debug_path) + ".build-id/" + to_hex(id.data(), 1) + '/' +
                to_hex(id.data() + 1, id.size() - 1) + ".debug";
     XBT_DEBUG("Checking debug file: %s", filename.c_str());
-    if (access(filename.c_str(), F_OK) == 0) {
+    int fd = open(filename.c_str(), O_RDONLY);
+    if (fd != -1) {
       XBT_DEBUG("Found debug file: %s\n", hex.c_str());
-      return filename;
+      return fd;
     }
+    xbt_assert(errno != ENOENT, "Could not open file: %s", strerror(errno));
   }
   XBT_DEBUG("No debug info found for build ID %s\n", hex.data());
-  return std::string();
+  return -1;
 }
 
 /** @brief Populate the debugging information of the given ELF object
  *
- *  Read the DWARf information of the EFFL object and populate the
+ *  Read the DWARF information of the ELF object and populate the
  *  lists of types, variables, functions.
  */
 static void MC_load_dwarf(simgrid::mc::ObjectInformation* info)
@@ -994,9 +984,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);
@@ -1029,18 +1017,16 @@ static void MC_load_dwarf(simgrid::mc::ObjectInformation* info)
     close(fd);
 
     // Find the debug file using the build id:
-    std::string debug_file = find_by_build_id(build_id);
-    xbt_assert(not debug_file.empty(),
+    fd = find_by_build_id(build_id);
+    xbt_assert(fd != -1,
                "Missing debug info for %s with build-id %s\n"
                "You might want to install the suitable debugging package.\n",
                info->file_name.c_str(), to_hex(build_id).c_str());
 
     // Load the DWARF info from this file:
-    XBT_DEBUG("Load DWARF for %s from %s", info->file_name.c_str(), debug_file.c_str());
-    fd = open(debug_file.c_str(), O_RDONLY);
-    xbt_assert(fd >= 0, "Could not open file %s", debug_file.c_str());
+    XBT_DEBUG("Load DWARF for %s", info->file_name.c_str());
     dwarf = dwarf_begin(fd, DWARF_C_READ);
-    xbt_assert(dwarf != nullptr, "No DWARF info in %s for %s", debug_file.c_str(), info->file_name.c_str());
+    xbt_assert(dwarf != nullptr, "No DWARF info for %s", info->file_name.c_str());
     read_dwarf_info(info, dwarf);
     dwarf_end(dwarf);
     close(fd);
@@ -1147,24 +1133,32 @@ 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;
 }
 
 /*************************************************************************/
 
-void postProcessObjectInformation(const RemoteSimulation* process, ObjectInformation* info)
+void postProcessObjectInformation(const RemoteProcess* process, ObjectInformation* info)
 {
   for (auto& t : info->types) {
     Type* type    = &(t.second);