2024-11-08 23:07:30 +00:00
|
|
|
From 271b9abbbca3b334f95cb70141fac9ad2452f3f5 Mon Sep 17 00:00:00 2001
|
2024-11-06 20:39:21 +00:00
|
|
|
From: Christian Hergert <chergert@redhat.com>
|
|
|
|
Date: Thu, 10 Oct 2024 17:04:19 -0700
|
2024-11-08 23:07:30 +00:00
|
|
|
Subject: [PATCH 07/31] libsysprof: hoist fallback symbol creation
|
2024-11-06 20:39:21 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
|