From 2dc6b1b7a55641dc6e748290824f182f2d92badd Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Tue, 29 Aug 2023 13:41:49 -0700 Subject: [PATCH] libsysprof: truncate common prefix using debug dir If we have a path like /app/bin/gnome-builder and the debug prefix is /app/lib/debug then we don't want to end up with /app/lib/debug/app/bin as the real data directory is /app/lib/debug/bin. This often works with /usr because /usr/lib/debug/usr can link back to it's parent. But we should try to do the right thing instead of relying on that anyway. --- src/libsysprof/sysprof-elf-loader.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/libsysprof/sysprof-elf-loader.c b/src/libsysprof/sysprof-elf-loader.c index 3b82cf0c..9ba5fdcf 100644 --- a/src/libsysprof/sysprof-elf-loader.c +++ b/src/libsysprof/sysprof-elf-loader.c @@ -289,6 +289,31 @@ try_load_build_id (SysprofElfLoader *self, return FALSE; } +static const char * +skip_common_prefix (const char *path, + const char *other) +{ + const char *committed = path; + + /* If @path is "/app/bin/foo" and @other is "/app/lib/debug", we want + * to return "bin/foo", otherwise "/app/bin/foo". + */ + + while (*path && *other) + { + if (*path != *other) + break; + + if (*path == '/') + committed = path; + + path++; + other++; + } + + return committed; +} + static void sysprof_elf_loader_annotate (SysprofElfLoader *self, SysprofMountNamespace *mount_namespace, @@ -309,11 +334,13 @@ sysprof_elf_loader_annotate (SysprofElfLoader *self, g_autofree char *directory_name = NULL; g_autofree char *debug_path = NULL; g_autofree char *container_path = NULL; + const char *short_directory_name; const char *debug_dir = self->debug_dirs[i]; const char *build_id; directory_name = g_path_get_dirname (orig_file); - debug_path = g_build_filename (debug_dir, directory_name, debug_link, NULL); + short_directory_name = skip_common_prefix (directory_name, debug_dir); + debug_path = g_build_filename (debug_dir, short_directory_name, debug_link, NULL); build_id = sysprof_elf_get_build_id (elf); if (try_load_build_id (self, mount_namespace, elf, build_id, debug_dir))