diff --git a/src/libsysprof-analyze/sysprof-elf-private.h b/src/libsysprof-analyze/sysprof-elf-private.h index 146bc2de..b4d0f737 100644 --- a/src/libsysprof-analyze/sysprof-elf-private.h +++ b/src/libsysprof-analyze/sysprof-elf-private.h @@ -42,7 +42,8 @@ const char *sysprof_elf_get_debug_link (SysprofElf *self); char *sysprof_elf_get_symbol_at_address (SysprofElf *self, guint64 address, guint64 *begin_address, - guint64 *end_address); + guint64 *end_address, + gboolean *is_fallback); SysprofElf *sysprof_elf_get_debug_link_elf (SysprofElf *self); void sysprof_elf_set_debug_link_elf (SysprofElf *self, SysprofElf *debug_link_elf); diff --git a/src/libsysprof-analyze/sysprof-elf-symbolizer.c b/src/libsysprof-analyze/sysprof-elf-symbolizer.c index 9fe85171..d522cf38 100644 --- a/src/libsysprof-analyze/sysprof-elf-symbolizer.c +++ b/src/libsysprof-analyze/sysprof-elf-symbolizer.c @@ -63,6 +63,7 @@ sysprof_elf_symbolizer_symbolize (SysprofSymbolizer *symbolizer, g_autofree char *name = NULL; const char *path; const char *build_id; + gboolean is_fallback = FALSE; guint64 map_begin; guint64 map_end; guint64 relative_address; @@ -70,6 +71,7 @@ sysprof_elf_symbolizer_symbolize (SysprofSymbolizer *symbolizer, guint64 end_address; guint64 file_inode; guint64 file_offset; + SysprofSymbol *ret; if (process_info == NULL || process_info->address_layout == NULL || @@ -119,7 +121,8 @@ sysprof_elf_symbolizer_symbolize (SysprofSymbolizer *symbolizer, if (!(name = sysprof_elf_get_symbol_at_address (elf, relative_address, &begin_address, - &end_address))) + &end_address, + &is_fallback))) goto fallback; /* Sanitize address ranges if we have to. Sometimes that can happen @@ -130,12 +133,15 @@ sysprof_elf_symbolizer_symbolize (SysprofSymbolizer *symbolizer, if (end_address == begin_address) end_address++; - return _sysprof_symbol_new (sysprof_strings_get (strings, name), - sysprof_strings_get (strings, path), - sysprof_strings_get (strings, sysprof_elf_get_nick (elf)), - map_begin + (begin_address - file_offset), - map_begin + (end_address - file_offset), - SYSPROF_SYMBOL_KIND_USER); + ret = _sysprof_symbol_new (sysprof_strings_get (strings, name), + sysprof_strings_get (strings, path), + sysprof_strings_get (strings, sysprof_elf_get_nick (elf)), + map_begin + (begin_address - file_offset), + map_begin + (end_address - file_offset), + SYSPROF_SYMBOL_KIND_USER); + ret->is_fallback = is_fallback; + + return ret; fallback: /* Fallback, we failed to locate the symbol within a file we can @@ -148,9 +154,12 @@ fallback: begin_address = address; end_address = address + 1; - return _sysprof_symbol_new (sysprof_strings_get (strings, name), - NULL, NULL, begin_address, end_address, - SYSPROF_SYMBOL_KIND_USER); + ret = _sysprof_symbol_new (sysprof_strings_get (strings, name), + NULL, NULL, begin_address, end_address, + SYSPROF_SYMBOL_KIND_USER); + ret->is_fallback = TRUE; + + return ret; } static void diff --git a/src/libsysprof-analyze/sysprof-elf.c b/src/libsysprof-analyze/sysprof-elf.c index 2542346a..96f6825b 100644 --- a/src/libsysprof-analyze/sysprof-elf.c +++ b/src/libsysprof-analyze/sysprof-elf.c @@ -369,7 +369,8 @@ sysprof_elf_get_symbol_at_address_internal (SysprofElf *self, guint64 address, guint64 *begin_address, guint64 *end_address, - guint64 text_offset) + guint64 text_offset, + gboolean *is_fallback) { const ElfSym *symbol; char *ret = NULL; @@ -380,7 +381,7 @@ sysprof_elf_get_symbol_at_address_internal (SysprofElf *self, if (self->debug_link_elf != NULL) { - ret = sysprof_elf_get_symbol_at_address_internal (self->debug_link_elf, filename, address, begin_address, end_address, text_offset); + ret = sysprof_elf_get_symbol_at_address_internal (self->debug_link_elf, filename, address, begin_address, end_address, text_offset, is_fallback); if (ret != NULL) return ret; @@ -409,6 +410,8 @@ sysprof_elf_get_symbol_at_address_internal (SysprofElf *self, begin = address; end = address + 1; ret = g_strdup_printf ("In File %s+0x%"G_GINT64_MODIFIER"x", filename, address); + if (is_fallback) + *is_fallback = TRUE; } if (begin_address) @@ -424,14 +427,16 @@ char * sysprof_elf_get_symbol_at_address (SysprofElf *self, guint64 address, guint64 *begin_address, - guint64 *end_address) + guint64 *end_address, + gboolean *is_fallback) { return sysprof_elf_get_symbol_at_address_internal (self, self->file, address, begin_address, end_address, - self->text_offset); + self->text_offset, + is_fallback); } /** diff --git a/src/libsysprof-analyze/sysprof-kallsyms-symbolizer.c b/src/libsysprof-analyze/sysprof-kallsyms-symbolizer.c index 0852cf5f..c3241b32 100644 --- a/src/libsysprof-analyze/sysprof-kallsyms-symbolizer.c +++ b/src/libsysprof-analyze/sysprof-kallsyms-symbolizer.c @@ -291,15 +291,19 @@ sysprof_kallsyms_symbolizer_symbolize (SysprofSymbolizer *symbolizer, failure: { + SysprofSymbol *ret; char name[64]; g_snprintf (name, sizeof name, "In Kernel+0x%"G_GINT64_MODIFIER"x", address); - return _sysprof_symbol_new (sysprof_strings_get (strings, name), - NULL, - g_ref_string_acquire (linux_string), - address, - address + 1, - SYSPROF_SYMBOL_KIND_KERNEL); + ret = _sysprof_symbol_new (sysprof_strings_get (strings, name), + NULL, + g_ref_string_acquire (linux_string), + address, + address + 1, + SYSPROF_SYMBOL_KIND_KERNEL); + ret->is_fallback = TRUE; + + return ret; } } diff --git a/src/libsysprof-analyze/sysprof-symbol-cache.c b/src/libsysprof-analyze/sysprof-symbol-cache.c index 5e9c97ef..0166ed44 100644 --- a/src/libsysprof-analyze/sysprof-symbol-cache.c +++ b/src/libsysprof-analyze/sysprof-symbol-cache.c @@ -251,6 +251,9 @@ sysprof_symbol_cache_populate_packed (SysprofSymbolCache *self, SysprofPackedSymbol packed; SysprofSymbol *symbol = node->symbol; + if (symbol->is_fallback) + continue; + packed.addr_begin = symbol->begin_address; packed.addr_end = symbol->end_address; packed.pid = pid; diff --git a/src/libsysprof-analyze/sysprof-symbol-private.h b/src/libsysprof-analyze/sysprof-symbol-private.h index 0fb79111..0e99f6c0 100644 --- a/src/libsysprof-analyze/sysprof-symbol-private.h +++ b/src/libsysprof-analyze/sysprof-symbol-private.h @@ -39,6 +39,7 @@ struct _SysprofSymbol SysprofAddress end_address; guint kind : 3; + guint is_fallback : 1; }; SysprofSymbol *_sysprof_symbol_new (GRefString *name,