From 47c3503938c863d55c835463d8815b5fa4ab8326 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Sat, 24 Dec 2022 20:19:27 +0100 Subject: [PATCH 3/4] libbacktrace: Support multiple build id directories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gdb supports multiple debug directories separated by colons: https://github.com/bminor/binutils-gdb/blob/fcbfb25dcca625a7f999ec51d48b6fc3a32123c3/gdb/build-id.c#L136-L142 This is useful for example when using dwarffs in addition to debug data installed using distribution’s package manager. --- elf.c | 57 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/elf.c b/elf.c index 21fbe4f..ccffa95 100644 --- a/elf.c +++ b/elf.c @@ -865,12 +865,12 @@ elf_readlink (struct backtrace_state *state, const char *filename, when the build ID is known is in /usr/lib/debug/.build-id. */ static int -elf_open_debugfile_by_buildid (struct backtrace_state *state, +elf_open_debugfile_by_buildid (const char * const prefix, + struct backtrace_state *state, const char *buildid_data, size_t buildid_size, backtrace_error_callback error_callback, void *data) { - const char * const prefix = SYSTEM_DEBUG_DIR BUILD_ID_DIR; const size_t prefix_len = strlen (prefix); const char * const suffix = ".debug"; const size_t suffix_len = strlen (suffix); @@ -6947,27 +6947,42 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, if (buildid_data != NULL) { int d; + char debug_directories[strlen(SYSTEM_DEBUG_DIR) + 1]; + char *debug_dir; - d = elf_open_debugfile_by_buildid (state, buildid_data, buildid_size, - error_callback, data); - if (d >= 0) - { - int ret; + strcpy(debug_directories, SYSTEM_DEBUG_DIR); - elf_release_view (state, &buildid_view, error_callback, data); - if (debuglink_view_valid) - elf_release_view (state, &debuglink_view, error_callback, data); - if (debugaltlink_view_valid) - elf_release_view (state, &debugaltlink_view, error_callback, data); - ret = elf_add (state, "", d, NULL, 0, base_address, opd, - error_callback, data, fileline_fn, found_sym, - found_dwarf, NULL, 0, 1, NULL, 0); - if (ret < 0) - backtrace_close (d, error_callback, data); - else if (descriptor >= 0) - backtrace_close (descriptor, error_callback, data); - return ret; - } + debug_dir = strtok (debug_directories, ":"); + while (debug_dir != NULL) + { + char prefix[strlen(debug_dir) + strlen(BUILD_ID_DIR) + 1]; + strcpy(prefix, debug_dir); + strcat(prefix, BUILD_ID_DIR); + + d = elf_open_debugfile_by_buildid (prefix, state, buildid_data, buildid_size, + error_callback, data); + + if (d >= 0) + { + int ret; + + elf_release_view (state, &buildid_view, error_callback, data); + if (debuglink_view_valid) + elf_release_view (state, &debuglink_view, error_callback, data); + if (debugaltlink_view_valid) + elf_release_view (state, &debugaltlink_view, error_callback, data); + ret = elf_add (state, "", d, NULL, 0, base_address, opd, + error_callback, data, fileline_fn, found_sym, + found_dwarf, NULL, 0, 1, NULL, 0); + if (ret < 0) + backtrace_close (d, error_callback, data); + else if (descriptor >= 0) + backtrace_close (descriptor, error_callback, data); + return ret; + } + + debug_dir = strtok (NULL, ":"); + } } if (buildid_view_valid) -- 2.43.1