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.
This commit is contained in:
Christian Hergert
2023-08-28 13:28:59 -07:00
parent e6d9f7c849
commit aad3441fee
2 changed files with 24 additions and 7 deletions

View File

@ -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;
}

View File

@ -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;
}