X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/2cee965a59bc4c1b024ddd0e10b64dc065044778..7a09e5523184d3d38ac040b732ed60d91308004e:/src/mc/mc_dwarf.cpp diff --git a/src/mc/mc_dwarf.cpp b/src/mc/mc_dwarf.cpp index 64b71b037a..3d086788f7 100644 --- a/src/mc/mc_dwarf.cpp +++ b/src/mc/mc_dwarf.cpp @@ -38,7 +38,7 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_dwarf, mc, "DWARF processing"); * * The default for a given language is defined in the DWARF spec. * - * \param language consant as defined by the DWARf spec + * \param language constant as defined by the DWARf spec */ static uint64_t MC_dwarf_default_lower_bound(int lang); @@ -67,7 +67,7 @@ static uint64_t MC_dwarf_array_element_count(Dwarf_Die * die, Dwarf_Die * unit); * \param info the resulting object fot the library/binary file (output) * \param die the current DIE * \param unit the DIE of the compile unit of the current DIE - * \param frame containg frame if any + * \param frame containing frame if any */ static void MC_dwarf_handle_die(simgrid::mc::ObjectInformation* info, Dwarf_Die * die, Dwarf_Die * unit, simgrid::mc::Frame* frame, @@ -79,12 +79,12 @@ static void MC_dwarf_handle_type_die(simgrid::mc::ObjectInformation* info, Dwarf Dwarf_Die * unit, simgrid::mc::Frame* frame, const char *ns); -/** \brief Calls MC_dwarf_handle_die on all childrend of the given die +/** \brief Calls MC_dwarf_handle_die on all children of the given die * * \param info the resulting object fot the library/binary file (output) * \param die the current DIE * \param unit the DIE of the compile unit of the current DIE - * \param frame containg frame if any + * \param frame containing frame if any */ static void MC_dwarf_handle_children(simgrid::mc::ObjectInformation* info, Dwarf_Die * die, Dwarf_Die * unit, simgrid::mc::Frame* frame, @@ -95,7 +95,7 @@ static void MC_dwarf_handle_children(simgrid::mc::ObjectInformation* info, Dwarf * \param info the resulting object fot the library/binary file (output) * \param die the current DIE * \param unit the DIE of the compile unit of the current DIE - * \param frame containg frame if any + * \param frame containing frame if any */ static void MC_dwarf_handle_variable_die(simgrid::mc::ObjectInformation* info, Dwarf_Die * die, Dwarf_Die * unit, simgrid::mc::Frame* frame, @@ -585,7 +585,7 @@ static void MC_dwarf_add_members(simgrid::mc::ObjectInformation* info, Dwarf_Die if (boost::algorithm::starts_with(member.name, "__vptr$") || boost::algorithm::starts_with(member.name, "__vptr.")) member.flags |= simgrid::mc::Member::VIRTUAL_POINTER_FLAG; - // A cleaner stolution would be to check against the type: + // A cleaner solution would be to check against the type: // --- // tag: DW_TAG_member // name: "_vptr$Foo" @@ -1044,6 +1044,9 @@ void read_dwarf_info(simgrid::mc::ObjectInformation* info, Dwarf* dwarf) static std::vector get_build_id(Elf* elf) { + // Summary: the GNU build ID is stored in a ("GNU, NT_GNU_BUILD_ID) note + // found in a PT_NOTE entry in the program header table. + size_t phnum; if (elf_getphdrnum (elf, &phnum) != 0) xbt_die("Could not read program headers"); @@ -1059,22 +1062,21 @@ std::vector get_build_id(Elf* elf) // Iterate over the notes and find the NT_GNU_BUILD_ID one: size_t pos = 0; - while (1) { + while (pos < data->d_size) { GElf_Nhdr nhdr; + // Location of the name within Elf_Data: size_t name_pos; size_t desc_pos; pos = gelf_getnote(data, pos, &nhdr, &name_pos, &desc_pos); - // A note is identified by a name "GNU" and a integer type within - // the namespace defined by this name (here NT_GNU_BUILD_ID): + // A build ID note is identified by the pair ("GNU", NT_GNU_BUILD_ID) + // (a namespace and a type within this namespace): if (nhdr.n_type == NT_GNU_BUILD_ID && nhdr.n_namesz == sizeof("GNU") && memcmp((char*) data->d_buf + name_pos, "GNU", sizeof("GNU")) == 0) { - - // Found the NT_GNU_BUILD_ID note: + XBT_DEBUG("Found GNU/NT_GNU_BUILD_ID note"); char* start = (char*) data->d_buf + desc_pos; char* end = (char*) start + nhdr.n_descsz; return std::vector(start, end); - } } @@ -1129,18 +1131,25 @@ const char* debug_paths[] = { * This is one of the mechanisms used for * [separate debug files](https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html). */ +// Example: +// /usr/lib/debug/.build-id/0b/dc77f1c29aea2b14ff5acd9a19ab3175ffdeae.debug static std::string find_by_build_id(std::vector id) { std::string filename; + std::string hex = to_hex(id); for (const char* debug_path : debug_paths) { - filename = debug_path; - filename += ".build-id/" + to_hex(id.data(), 1) + '/' + // Example: + 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) + if (access(filename.c_str(), F_OK) == 0) { + XBT_DEBUG("Found debug file: %s\n", hex.c_str()); return filename; + } } + XBT_DEBUG("Not debuf info found for build ID %s\n", hex.data()); return std::string(); } @@ -1150,7 +1159,7 @@ std::string find_by_build_id(std::vector id) * lists of types, variables, functions. */ static -void MC_dwarf_get_variables(simgrid::mc::ObjectInformation* info) +void MC_load_dwarf(simgrid::mc::ObjectInformation* info) { if (elf_version(EV_CURRENT) == EV_NONE) xbt_die("libelf initialization error"); @@ -1161,12 +1170,12 @@ void MC_dwarf_get_variables(simgrid::mc::ObjectInformation* info) xbt_die("Could not open file %s", info->file_name.c_str()); Elf* elf = elf_begin(fd, ELF_C_READ, nullptr); if (elf == nullptr) - xbt_die("Not an ELF file 1"); + xbt_die("Not an ELF file"); Elf_Kind kind = elf_kind(elf); if (kind != ELF_K_ELF) - xbt_die("Not an ELF file 2"); + xbt_die("Not an ELF file"); - // Remember if this is a `ET_EXEC` (fixed location) or `ET_DYN` (relocatable): + // Remember if this is a `ET_EXEC` (fixed location) or `ET_DYN`: Elf64_Half type = get_type(elf); if (type == ET_EXEC) info->flags |= simgrid::mc::ObjectInformation::Executable; @@ -1182,8 +1191,15 @@ void MC_dwarf_get_variables(simgrid::mc::ObjectInformation* info) } dwarf_end(dwarf); - // If there was no DWARF in the file, try to find it in a separate file - // with NT_GNU_BUILD_ID: + // If there was no DWARF in the file, try to find it in a separate file. + // Different methods might be used to store the DWARF informations: + // * GNU NT_GNU_BUILD_ID; + // * .gnu_debuglink. + // See https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html + // for reference of what we are doing. + + // Try with NT_GNU_BUILD_ID: we find the build ID in the ELF file and then + // use this ID to find the file in some known locations in the filesystem. std::vector build_id = get_build_id(elf); if (!build_id.empty()) { elf_end(elf); @@ -1193,8 +1209,7 @@ void MC_dwarf_get_variables(simgrid::mc::ObjectInformation* info) std::string debug_file = find_by_build_id(build_id); if (debug_file.empty()) { std::string hex = to_hex(build_id); - xbt_die( - "Missing debug info for %s with build-id %s\n" + xbt_die("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(), hex.c_str()); } @@ -1215,9 +1230,10 @@ void MC_dwarf_get_variables(simgrid::mc::ObjectInformation* info) return; } - // TODO, try to find DWARF info using debug-link. - // Is this method really used anywhere? + // TODO, try to find DWARF info using .gnu_debuglink. + elf_end(elf); + close(fd); xbt_die("Debugging information not found for %s\n" "Try recompiling with -g\n", info->file_name.c_str()); @@ -1343,7 +1359,7 @@ std::shared_ptr createObjectInformation( std::make_shared(); result->file_name = name; simgrid::mc::find_object_address(maps, result.get()); - MC_dwarf_get_variables(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) @@ -1393,7 +1409,7 @@ namespace dwarf { * * DWARF and libunwind does not use the same convention for numbering the * registers on some architectures. The function makes the necessary - * convertion. + * conversion. */ int dwarf_register_to_libunwind(int dwarf_register) { @@ -1401,7 +1417,7 @@ int dwarf_register_to_libunwind(int dwarf_register) // It seems for this arch, DWARF and libunwind agree in the numbering: return dwarf_register; #elif defined(__i386__) - // Could't find the authoritative source of information for this. + // Couldn't find the authoritative source of information for this. // This is inspired from http://source.winehq.org/source/dlls/dbghelp/cpu_i386.c#L517. switch (dwarf_register) { case 0: