From: Martin Quinson Date: Sun, 14 Mar 2021 14:09:13 +0000 (+0100) Subject: MC: lazily load the dwarf information X-Git-Tag: v3.27~137 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/7a0c1d1c6f127e4a62f49e5f9131f8c450b9f3ac MC: lazily load the dwarf information --- diff --git a/src/mc/inspect/ObjectInformation.cpp b/src/mc/inspect/ObjectInformation.cpp index e78ecc8e2c..e94f2552d4 100644 --- a/src/mc/inspect/ObjectInformation.cpp +++ b/src/mc/inspect/ObjectInformation.cpp @@ -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; diff --git a/src/mc/inspect/ObjectInformation.hpp b/src/mc/inspect/ObjectInformation.hpp index eb5e219f14..a9ed10075a 100644 --- a/src/mc/inspect/ObjectInformation.hpp +++ b/src/mc/inspect/ObjectInformation.hpp @@ -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) * diff --git a/src/mc/inspect/mc_dwarf.cpp b/src/mc/inspect/mc_dwarf.cpp index a11a069d7a..d7b1868895 100644 --- a/src/mc/inspect/mc_dwarf.cpp +++ b/src/mc/inspect/mc_dwarf.cpp @@ -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 createObjectInformation(std::vector const& maps, const char* name) { auto result = std::make_shared(); 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; } diff --git a/src/mc/remote/RemoteProcess.cpp b/src/mc/remote/RemoteProcess.cpp index 0899bd7069..41cacdc6a9 100644 --- a/src/mc/remote/RemoteProcess.cpp +++ b/src/mc/remote/RemoteProcess.cpp @@ -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)); } diff --git a/teshsuite/mc/dwarf/dwarf.cpp b/teshsuite/mc/dwarf/dwarf.cpp index 78cff65b8c..39739ca9a1 100644 --- a/teshsuite/mc/dwarf/dwarf.cpp +++ b/teshsuite/mc/dwarf/dwarf.cpp @@ -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);