From 64e1f7898211cbb000f6034b7dc54fca677cd818 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Thu, 10 Oct 2024 17:04:19 -0700 Subject: [PATCH 07/33] libsysprof: hoist fallback symbol creation This makes sure that we get that even when not using the Elf symbolizer but also means we can fallback through the Elf symbolizer into the debuginfod symbolizer. --- src/libsysprof/sysprof-document-symbols.c | 69 ++++++++++++++++++++++- src/libsysprof/sysprof-elf-symbolizer.c | 24 +------- 2 files changed, 69 insertions(+), 24 deletions(-) diff --git a/src/libsysprof/sysprof-document-symbols.c b/src/libsysprof/sysprof-document-symbols.c index 2f8d1849..828c7fb6 100644 --- a/src/libsysprof/sysprof-document-symbols.c +++ b/src/libsysprof/sysprof-document-symbols.c @@ -85,6 +85,71 @@ symbolize_free (Symbolize *state) g_free (state); } +static SysprofSymbol * +do_symbolize (SysprofSymbolizer *symbolizer, + SysprofStrings *strings, + SysprofProcessInfo *process_info, + SysprofAddressContext last_context, + SysprofAddress address) +{ + SysprofDocumentMmap *map; + g_autofree char *name = NULL; + SysprofSymbol *ret; + const char *nick = NULL; + const char *path; + guint64 map_begin; + guint64 map_end; + guint64 relative_address; + guint64 begin_address; + guint64 end_address; + guint64 file_offset; + + if ((ret = _sysprof_symbolizer_symbolize (symbolizer, strings, process_info, last_context, address))) + return ret; + + /* Fallback, we failed to locate the symbol within a file we can + * access, so tell the user about what file contained the symbol + * and where (relative to that file) the IP was. + */ + + if (!(map = sysprof_address_layout_lookup (process_info->address_layout, address))) + return NULL; + + map_begin = sysprof_document_mmap_get_start_address (map); + map_end = sysprof_document_mmap_get_end_address (map); + + g_assert (address >= map_begin); + g_assert (address < map_end); + + file_offset = sysprof_document_mmap_get_file_offset (map); + + relative_address = address; + relative_address -= map_begin; + relative_address += file_offset; + + path = sysprof_document_mmap_get_file (map); + + begin_address = CLAMP (begin_address, file_offset, file_offset + (map_end - map_begin)); + end_address = CLAMP (end_address, file_offset, file_offset + (map_end - map_begin)); + if (end_address == begin_address) + end_address++; + + name = g_strdup_printf ("In File %s+0x%"G_GINT64_MODIFIER"x", + sysprof_document_mmap_get_file (map), + relative_address); + begin_address = address; + end_address = address + 1; + + ret = _sysprof_symbol_new (sysprof_strings_get (strings, name), + sysprof_strings_get (strings, path), + sysprof_strings_get (strings, nick), + begin_address, end_address, + SYSPROF_SYMBOL_KIND_USER); + ret->is_fallback = TRUE; + + return ret; +} + static void add_traceable (SysprofDocumentSymbols *self, SysprofStrings *strings, @@ -123,7 +188,7 @@ add_traceable (SysprofDocumentSymbols *self, if (sysprof_symbol_cache_lookup (self->kernel_symbols, address) != NULL) continue; - if ((symbol = _sysprof_symbolizer_symbolize (symbolizer, strings, process_info, last_context, address))) + if ((symbol = do_symbolize (symbolizer, strings, process_info, last_context, address))) sysprof_symbol_cache_take (self->kernel_symbols, g_steal_pointer (&symbol)); } else @@ -134,7 +199,7 @@ add_traceable (SysprofDocumentSymbols *self, sysprof_symbol_cache_lookup (process_info->symbol_cache, address) != NULL) continue; - if ((symbol = _sysprof_symbolizer_symbolize (symbolizer, strings, process_info, last_context, address))) + if ((symbol = do_symbolize (symbolizer, strings, process_info, last_context, address))) sysprof_symbol_cache_take (process_info->symbol_cache, g_steal_pointer (&symbol)); } } diff --git a/src/libsysprof/sysprof-elf-symbolizer.c b/src/libsysprof/sysprof-elf-symbolizer.c index f7aabef7..05bd1d6c 100644 --- a/src/libsysprof/sysprof-elf-symbolizer.c +++ b/src/libsysprof/sysprof-elf-symbolizer.c @@ -113,7 +113,7 @@ sysprof_elf_symbolizer_symbolize (SysprofSymbolizer *symbolizer, build_id, file_inode, NULL))) - goto fallback; + return NULL; nick = sysprof_elf_get_nick (elf); @@ -124,7 +124,7 @@ sysprof_elf_symbolizer_symbolize (SysprofSymbolizer *symbolizer, relative_address, &begin_address, &end_address))) - goto fallback; + return NULL; /* Sanitize address ranges if we have to. Sometimes that can happen * for us, but it seems to be limited to glibc. @@ -142,26 +142,6 @@ sysprof_elf_symbolizer_symbolize (SysprofSymbolizer *symbolizer, SYSPROF_SYMBOL_KIND_USER); return ret; - -fallback: - /* Fallback, we failed to locate the symbol within a file we can - * access, so tell the user about what file contained the symbol - * and where (relative to that file) the IP was. - */ - name = g_strdup_printf ("In File %s+0x%"G_GINT64_MODIFIER"x", - sysprof_document_mmap_get_file (map), - relative_address); - begin_address = address; - end_address = address + 1; - - ret = _sysprof_symbol_new (sysprof_strings_get (strings, name), - sysprof_strings_get (strings, path), - sysprof_strings_get (strings, nick), - begin_address, end_address, - SYSPROF_SYMBOL_KIND_USER); - ret->is_fallback = TRUE; - - return ret; } static void -- 2.45.2