From aad3441fee34e6d3bc23f14c4a4f0124782d8811 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Mon, 28 Aug 2023 13:28:59 -0700 Subject: [PATCH] libsysprof: normalize binary path/nick empty strings If we get an empty string, just normalize that to NULL so that we can be more likely to match equality checks via hash comparison. Additionally, break hashes out into two so that we can improve the situation where some symbols do not have paths but still match. This can happen with bundled symbols. --- src/libsysprof/sysprof-symbol-private.h | 15 ++++++++++++--- src/libsysprof/sysprof-symbol.c | 16 ++++++++++++---- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/libsysprof/sysprof-symbol-private.h b/src/libsysprof/sysprof-symbol-private.h index 0e99f6c0..d6085bc3 100644 --- a/src/libsysprof/sysprof-symbol-private.h +++ b/src/libsysprof/sysprof-symbol-private.h @@ -30,6 +30,7 @@ struct _SysprofSymbol GObject parent_instance; guint hash; + guint simple_hash; GRefString *name; GRefString *binary_path; @@ -71,14 +72,22 @@ _sysprof_symbol_equal (const SysprofSymbol *a, if (a == b) return TRUE; - if (a->hash != b->hash) + if (a->simple_hash != b->simple_hash) return FALSE; if (a->kind != b->kind) return FALSE; - if (a->name == NULL || b->name == NULL) - return FALSE; + if (a->hash != b->hash) + { + /* Special case symbols w/o binary_path which can happen + * when we have symbols decoded from a bundled symbols. + */ + if (a->binary_path == NULL || b->binary_path == NULL) + return TRUE; + + return FALSE; + } return strcmp (a->name, b->name) == 0; } diff --git a/src/libsysprof/sysprof-symbol.c b/src/libsysprof/sysprof-symbol.c index 6db132a6..ed09d216 100644 --- a/src/libsysprof/sysprof-symbol.c +++ b/src/libsysprof/sysprof-symbol.c @@ -161,15 +161,26 @@ _sysprof_symbol_new (GRefString *name, { SysprofSymbol *self; + if (binary_nick != NULL && binary_nick[0] == 0) + binary_nick = NULL; + + if (binary_path != NULL && binary_path[0] == 0) + binary_path = NULL; + self = g_object_new (SYSPROF_TYPE_SYMBOL, NULL); self->name = name; self->binary_path = binary_path; self->binary_nick = binary_nick; self->begin_address = begin_address; self->end_address = end_address; - self->hash = g_str_hash (name); + self->simple_hash = g_str_hash (name); self->kind = kind; + if (binary_nick != NULL) + self->simple_hash ^= g_str_hash (binary_nick); + + self->hash = self->simple_hash; + /* If we got a path for the symbol, add that to the hash so that we * can be sure that we're working with a symbol in the same file when * there are collisions. @@ -185,9 +196,6 @@ _sysprof_symbol_new (GRefString *name, self->hash ^= g_str_hash (base); } - if (binary_nick != NULL) - self->hash ^= g_str_hash (binary_nick); - return self; }