From bd8a8ada2607136a56a75f3aeb761f6f3f9a090c Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Wed, 24 Feb 2021 18:59:35 -0800 Subject: [PATCH] elf: track pid root when building lookaside buffers We want to know the location of our root if it was specified in the capture file. Such is useful for decoding symbols that may not be reported right from perf tooling. This allows us to try to translate maps for processes in containers. --- src/libsysprof/sysprof-elf-symbol-resolver.c | 59 ++++++++++++-------- src/libsysprof/sysprof-map-lookaside.c | 16 ++++-- src/libsysprof/sysprof-map-lookaside.h | 21 ++++--- 3 files changed, 61 insertions(+), 35 deletions(-) diff --git a/src/libsysprof/sysprof-elf-symbol-resolver.c b/src/libsysprof/sysprof-elf-symbol-resolver.c index 2425ed66..c81de6f1 100644 --- a/src/libsysprof/sysprof-elf-symbol-resolver.c +++ b/src/libsysprof/sysprof-elf-symbol-resolver.c @@ -142,34 +142,49 @@ sysprof_elf_symbol_resolver_load (SysprofSymbolResolver *resolver, while (sysprof_capture_reader_peek_type (reader, &type)) { - const SysprofCaptureMap *ev; - SysprofMapLookaside *lookaside; - SysprofMap map; + if (type == SYSPROF_CAPTURE_FRAME_MAP) + { + const SysprofCaptureMap *ev = sysprof_capture_reader_read_map (reader); + SysprofMapLookaside *lookaside = g_hash_table_lookup (self->lookasides, GINT_TO_POINTER (ev->frame.pid)); + SysprofMap map; - if (type != SYSPROF_CAPTURE_FRAME_MAP) + map.start = ev->start; + map.end = ev->end; + map.offset = ev->offset; + map.inode = ev->inode; + map.filename = ev->filename; + + if (lookaside == NULL) + { + lookaside = sysprof_map_lookaside_new (); + g_hash_table_insert (self->lookasides, GINT_TO_POINTER (ev->frame.pid), lookaside); + } + + sysprof_map_lookaside_insert (lookaside, &map); + } + else if (type == SYSPROF_CAPTURE_FRAME_PID_ROOT) + { + const SysprofCapturePidRoot *ev = sysprof_capture_reader_read_pid_root (reader); + SysprofMapLookaside *lookaside = g_hash_table_lookup (self->lookasides, GINT_TO_POINTER (ev->frame.pid)); + + if (lookaside == NULL) + { + lookaside = sysprof_map_lookaside_new (); + g_hash_table_insert (self->lookasides, GINT_TO_POINTER (ev->frame.pid), lookaside); + } + + /* Someday we might need to support more layers, but currently + * only the base layer (0) is used. + */ + if (ev->layer == 0) + sysprof_map_lookaside_set_root (lookaside, ev->path); + } + else { if (!sysprof_capture_reader_skip (reader)) return; continue; } - - ev = sysprof_capture_reader_read_map (reader); - - map.start = ev->start; - map.end = ev->end; - map.offset = ev->offset; - map.inode = ev->inode; - map.filename = ev->filename; - - lookaside = g_hash_table_lookup (self->lookasides, GINT_TO_POINTER (ev->frame.pid)); - - if (lookaside == NULL) - { - lookaside = sysprof_map_lookaside_new (); - g_hash_table_insert (self->lookasides, GINT_TO_POINTER (ev->frame.pid), lookaside); - } - - sysprof_map_lookaside_insert (lookaside, &map); } } diff --git a/src/libsysprof/sysprof-map-lookaside.c b/src/libsysprof/sysprof-map-lookaside.c index 277e7f66..9881e4aa 100644 --- a/src/libsysprof/sysprof-map-lookaside.c +++ b/src/libsysprof/sysprof-map-lookaside.c @@ -24,12 +24,6 @@ #include "sysprof-map-lookaside.h" -struct _SysprofMapLookaside -{ - GSequence *seq; - GStringChunk *chunk; -}; - static gint sysprof_map_compare (gconstpointer a, gconstpointer b, @@ -107,6 +101,16 @@ sysprof_map_lookaside_insert (SysprofMapLookaside *self, g_sequence_insert_sorted (self->seq, copy, sysprof_map_compare, NULL); } +void +sysprof_map_lookaside_set_root (SysprofMapLookaside *self, + const char *root) +{ + g_assert (self != NULL); + g_assert (root != NULL); + + self->root = g_string_chunk_insert_const (self->chunk, root); +} + const SysprofMap * sysprof_map_lookaside_lookup (SysprofMapLookaside *self, SysprofCaptureAddress address) diff --git a/src/libsysprof/sysprof-map-lookaside.h b/src/libsysprof/sysprof-map-lookaside.h index ef068562..b91a03a6 100644 --- a/src/libsysprof/sysprof-map-lookaside.h +++ b/src/libsysprof/sysprof-map-lookaside.h @@ -26,7 +26,12 @@ G_BEGIN_DECLS -typedef struct _SysprofMapLookaside SysprofMapLookaside; +typedef struct _SysprofMapLookaside +{ + GSequence *seq; + GStringChunk *chunk; + const gchar *root; +} SysprofMapLookaside; typedef struct { @@ -37,12 +42,14 @@ typedef struct const gchar *filename; } SysprofMap; -SysprofMapLookaside *sysprof_map_lookaside_new (void); -void sysprof_map_lookaside_insert (SysprofMapLookaside *self, - const SysprofMap *map); -const SysprofMap *sysprof_map_lookaside_lookup (SysprofMapLookaside *self, - SysprofCaptureAddress address); -void sysprof_map_lookaside_free (SysprofMapLookaside *self); +SysprofMapLookaside *sysprof_map_lookaside_new (void); +void sysprof_map_lookaside_insert (SysprofMapLookaside *self, + const SysprofMap *map); +void sysprof_map_lookaside_set_root (SysprofMapLookaside *self, + const gchar *root); +const SysprofMap *sysprof_map_lookaside_lookup (SysprofMapLookaside *self, + SysprofCaptureAddress address); +void sysprof_map_lookaside_free (SysprofMapLookaside *self); G_DEFINE_AUTOPTR_CLEANUP_FUNC (SysprofMapLookaside, sysprof_map_lookaside_free)