X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/706dd4584b4002e0d948b81d103dd5c4b70db077..8cf6e30af8de6686461b6b1b52ba578df01de985:/src/mc/mc_dwarf.cpp diff --git a/src/mc/mc_dwarf.cpp b/src/mc/mc_dwarf.cpp index d619a96667..c177458fa2 100644 --- a/src/mc/mc_dwarf.cpp +++ b/src/mc/mc_dwarf.cpp @@ -874,7 +874,7 @@ static void MC_dwarf_handle_scope_die(simgrid::mc::ObjectInformation* info, Dwar if (klass == simgrid::dwarf::TagClass::Subprogram) { const char *name = MC_dwarf_attr_integrate_string(die, DW_AT_name); - if (ns) + if (name && ns) frame.name = std::string(ns) + "::" + name; else if (name) frame.name = name; @@ -1044,6 +1044,10 @@ void read_dwarf_info(simgrid::mc::ObjectInformation* info, Dwarf* dwarf) static std::vector get_build_id(Elf* elf) { +#ifdef __linux + // 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,26 +1063,26 @@ 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); - } } } +#endif return std::vector(); } @@ -1129,18 +1133,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 +1161,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 +1172,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 +1193,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 +1211,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 +1232,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 +1361,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)