mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-09 06:30:54 +00:00
libsysprof: attach symbol directories to ELF resolver
The goal here is to drop the sysprof-symbol-dirs.[ch] altogether in favor of modifying the resolver directories on the particular resolver directly.
This commit is contained in:
@ -145,14 +145,14 @@ get_build_id_file (ElfParser *elf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static ElfParser *
|
static ElfParser *
|
||||||
get_debuglink_file (ElfParser *elf,
|
get_debuglink_file (ElfParser *elf,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
char **new_name)
|
char **new_name,
|
||||||
|
const gchar * const *debug_dirs)
|
||||||
{
|
{
|
||||||
const char *basename;
|
const char *basename;
|
||||||
char *dir;
|
char *dir;
|
||||||
guint32 crc32;
|
guint32 crc32;
|
||||||
gchar **tries;
|
|
||||||
ElfParser *result = NULL;
|
ElfParser *result = NULL;
|
||||||
const char *build_id;
|
const char *build_id;
|
||||||
guint i;
|
guint i;
|
||||||
@ -173,11 +173,9 @@ get_debuglink_file (ElfParser *elf,
|
|||||||
|
|
||||||
dir = g_path_get_dirname (filename);
|
dir = g_path_get_dirname (filename);
|
||||||
|
|
||||||
tries = sysprof_symbol_dirs_get_paths (dir, basename);
|
for (i = 0; debug_dirs[i]; i++)
|
||||||
|
|
||||||
for (i = 0; tries[i]; i++)
|
|
||||||
{
|
{
|
||||||
const char *name = tries[i];
|
const char *name = debug_dirs[i];
|
||||||
ElfParser *parser = elf_parser_new (name, NULL);
|
ElfParser *parser = elf_parser_new (name, NULL);
|
||||||
guint32 file_crc;
|
guint32 file_crc;
|
||||||
const char *file_build_id;
|
const char *file_build_id;
|
||||||
@ -215,15 +213,15 @@ get_debuglink_file (ElfParser *elf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_free (dir);
|
g_free (dir);
|
||||||
g_strfreev (tries);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GList *
|
static GList *
|
||||||
get_debug_binaries (GList *files,
|
get_debug_binaries (GList *files,
|
||||||
ElfParser *elf,
|
ElfParser *elf,
|
||||||
const char *filename)
|
const char *filename,
|
||||||
|
const gchar * const *debug_dirs)
|
||||||
{
|
{
|
||||||
ElfParser *build_id_file;
|
ElfParser *build_id_file;
|
||||||
GHashTable *seen_names;
|
GHashTable *seen_names;
|
||||||
@ -249,7 +247,7 @@ get_debug_binaries (GList *files,
|
|||||||
|
|
||||||
g_hash_table_insert (seen_names, (char *)filename, (char *)filename);
|
g_hash_table_insert (seen_names, (char *)filename, (char *)filename);
|
||||||
|
|
||||||
elf = get_debuglink_file (elf, filename, &debug_name);
|
elf = get_debuglink_file (elf, filename, &debug_name, debug_dirs);
|
||||||
|
|
||||||
if (elf)
|
if (elf)
|
||||||
{
|
{
|
||||||
@ -354,7 +352,8 @@ get_vdso_bytes (size_t *length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bin_file_t *
|
bin_file_t *
|
||||||
bin_file_new (const char *filename)
|
bin_file_new (const char *filename,
|
||||||
|
const gchar * const *debug_dirs)
|
||||||
{
|
{
|
||||||
const gchar *real_filename = filename;
|
const gchar *real_filename = filename;
|
||||||
ElfParser *elf = NULL;
|
ElfParser *elf = NULL;
|
||||||
@ -393,7 +392,7 @@ bin_file_new (const char *filename)
|
|||||||
*/
|
*/
|
||||||
bf->text_offset = elf_parser_get_text_offset (elf);
|
bf->text_offset = elf_parser_get_text_offset (elf);
|
||||||
|
|
||||||
bf->elf_files = get_debug_binaries (bf->elf_files, elf, filename);
|
bf->elf_files = get_debug_binaries (bf->elf_files, elf, filename, debug_dirs);
|
||||||
bf->elf_files = g_list_append (bf->elf_files, elf);
|
bf->elf_files = g_list_append (bf->elf_files, elf);
|
||||||
|
|
||||||
bf->inode = read_inode (filename);
|
bf->inode = read_inode (filename);
|
||||||
@ -417,7 +416,7 @@ bin_file_free (bin_file_t *bin_file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const bin_symbol_t *
|
const bin_symbol_t *
|
||||||
bin_file_lookup_symbol (bin_file_t *bin_file,
|
bin_file_lookup_symbol (bin_file_t *bin_file,
|
||||||
gulong address)
|
gulong address)
|
||||||
{
|
{
|
||||||
GList *list;
|
GList *list;
|
||||||
|
|||||||
@ -32,19 +32,20 @@ typedef struct bin_symbol_t bin_symbol_t;
|
|||||||
|
|
||||||
/* Binary File */
|
/* Binary File */
|
||||||
|
|
||||||
bin_file_t *bin_file_new (const char *filename);
|
bin_file_t *bin_file_new (const char *filename,
|
||||||
void bin_file_free (bin_file_t *bin_file);
|
const gchar * const *debug_dirs);
|
||||||
const bin_symbol_t *bin_file_lookup_symbol (bin_file_t *bin_file,
|
void bin_file_free (bin_file_t *bin_file);
|
||||||
gulong address);
|
const bin_symbol_t *bin_file_lookup_symbol (bin_file_t *bin_file,
|
||||||
gboolean bin_file_check_inode (bin_file_t *bin_file,
|
gulong address);
|
||||||
ino_t inode);
|
gboolean bin_file_check_inode (bin_file_t *bin_file,
|
||||||
const char *bin_symbol_get_name (bin_file_t *bin_file,
|
ino_t inode);
|
||||||
const bin_symbol_t *symbol);
|
const char *bin_symbol_get_name (bin_file_t *bin_file,
|
||||||
gulong bin_symbol_get_address (bin_file_t *bin_file,
|
const bin_symbol_t *symbol);
|
||||||
const bin_symbol_t *symbol);
|
gulong bin_symbol_get_address (bin_file_t *bin_file,
|
||||||
void bin_symbol_get_address_range (bin_file_t *bin_file,
|
const bin_symbol_t *symbol);
|
||||||
const bin_symbol_t *symbol,
|
void bin_symbol_get_address_range (bin_file_t *bin_file,
|
||||||
gulong *begin,
|
const bin_symbol_t *symbol,
|
||||||
gulong *end);
|
gulong *begin,
|
||||||
|
gulong *end);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -25,12 +25,14 @@
|
|||||||
#include "binfile.h"
|
#include "binfile.h"
|
||||||
#include "elfparser.h"
|
#include "elfparser.h"
|
||||||
#include "sysprof-elf-symbol-resolver.h"
|
#include "sysprof-elf-symbol-resolver.h"
|
||||||
|
#include "sysprof-flatpak.h"
|
||||||
#include "sysprof-map-lookaside.h"
|
#include "sysprof-map-lookaside.h"
|
||||||
|
|
||||||
struct _SysprofElfSymbolResolver
|
struct _SysprofElfSymbolResolver
|
||||||
{
|
{
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
|
|
||||||
|
GArray *debug_dirs;
|
||||||
GHashTable *lookasides;
|
GHashTable *lookasides;
|
||||||
GHashTable *bin_files;
|
GHashTable *bin_files;
|
||||||
GHashTable *tag_cache;
|
GHashTable *tag_cache;
|
||||||
@ -45,6 +47,21 @@ G_DEFINE_TYPE_EXTENDED (SysprofElfSymbolResolver,
|
|||||||
G_IMPLEMENT_INTERFACE (SYSPROF_TYPE_SYMBOL_RESOLVER,
|
G_IMPLEMENT_INTERFACE (SYSPROF_TYPE_SYMBOL_RESOLVER,
|
||||||
symbol_resolver_iface_init))
|
symbol_resolver_iface_init))
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_flatpak (void)
|
||||||
|
{
|
||||||
|
static gsize did_init = FALSE;
|
||||||
|
static gboolean ret;
|
||||||
|
|
||||||
|
if (g_once_init_enter (&did_init))
|
||||||
|
{
|
||||||
|
ret = g_file_test ("/.flatpak-info", G_FILE_TEST_EXISTS);
|
||||||
|
g_once_init_leave (&did_init, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sysprof_elf_symbol_resolver_finalize (GObject *object)
|
sysprof_elf_symbol_resolver_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
@ -53,6 +70,7 @@ sysprof_elf_symbol_resolver_finalize (GObject *object)
|
|||||||
g_clear_pointer (&self->bin_files, g_hash_table_unref);
|
g_clear_pointer (&self->bin_files, g_hash_table_unref);
|
||||||
g_clear_pointer (&self->lookasides, g_hash_table_unref);
|
g_clear_pointer (&self->lookasides, g_hash_table_unref);
|
||||||
g_clear_pointer (&self->tag_cache, g_hash_table_unref);
|
g_clear_pointer (&self->tag_cache, g_hash_table_unref);
|
||||||
|
g_clear_pointer (&self->debug_dirs, g_array_unref);
|
||||||
|
|
||||||
G_OBJECT_CLASS (sysprof_elf_symbol_resolver_parent_class)->finalize (object);
|
G_OBJECT_CLASS (sysprof_elf_symbol_resolver_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@ -65,9 +83,29 @@ sysprof_elf_symbol_resolver_class_init (SysprofElfSymbolResolverClass *klass)
|
|||||||
object_class->finalize = sysprof_elf_symbol_resolver_finalize;
|
object_class->finalize = sysprof_elf_symbol_resolver_finalize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_element_string (gpointer data)
|
||||||
|
{
|
||||||
|
g_free (*(gchar **)data);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sysprof_elf_symbol_resolver_init (SysprofElfSymbolResolver *self)
|
sysprof_elf_symbol_resolver_init (SysprofElfSymbolResolver *self)
|
||||||
{
|
{
|
||||||
|
self->debug_dirs = g_array_new (TRUE, FALSE, sizeof (gchar *));
|
||||||
|
g_array_set_clear_func (self->debug_dirs, free_element_string);
|
||||||
|
sysprof_elf_symbol_resolver_add_debug_dir (self, "/usr/lib/debug");
|
||||||
|
sysprof_elf_symbol_resolver_add_debug_dir (self, "/usr/lib32/debug");
|
||||||
|
sysprof_elf_symbol_resolver_add_debug_dir (self, "/usr/lib64/debug");
|
||||||
|
|
||||||
|
if (is_flatpak ())
|
||||||
|
{
|
||||||
|
g_auto(GStrv) debug_dirs = sysprof_flatpak_debug_dirs ();
|
||||||
|
|
||||||
|
for (guint i = 0; debug_dirs[i]; i++)
|
||||||
|
sysprof_elf_symbol_resolver_add_debug_dir (self, debug_dirs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
self->lookasides = g_hash_table_new_full (NULL,
|
self->lookasides = g_hash_table_new_full (NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
@ -126,21 +164,6 @@ sysprof_elf_symbol_resolver_load (SysprofSymbolResolver *resolver,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
is_flatpak (void)
|
|
||||||
{
|
|
||||||
static gsize did_init = FALSE;
|
|
||||||
static gboolean ret;
|
|
||||||
|
|
||||||
if (g_once_init_enter (&did_init))
|
|
||||||
{
|
|
||||||
ret = g_file_test ("/.flatpak-info", G_FILE_TEST_EXISTS);
|
|
||||||
g_once_init_leave (&did_init, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bin_file_t *
|
static bin_file_t *
|
||||||
sysprof_elf_symbol_resolver_get_bin_file (SysprofElfSymbolResolver *self,
|
sysprof_elf_symbol_resolver_get_bin_file (SysprofElfSymbolResolver *self,
|
||||||
const gchar *filename)
|
const gchar *filename)
|
||||||
@ -154,6 +177,9 @@ sysprof_elf_symbol_resolver_get_bin_file (SysprofElfSymbolResolver *self,
|
|||||||
if (bin_file == NULL)
|
if (bin_file == NULL)
|
||||||
{
|
{
|
||||||
const gchar *alternate = filename;
|
const gchar *alternate = filename;
|
||||||
|
const gchar * const *dirs;
|
||||||
|
|
||||||
|
dirs = (const gchar * const *)(gpointer)self->debug_dirs->data;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we are in a new mount namespace, then rely on the sysprof_symbol_dirs
|
* If we are in a new mount namespace, then rely on the sysprof_symbol_dirs
|
||||||
@ -169,11 +195,11 @@ sysprof_elf_symbol_resolver_get_bin_file (SysprofElfSymbolResolver *self,
|
|||||||
if (is_flatpak () && g_str_has_prefix (filename, "/usr/"))
|
if (is_flatpak () && g_str_has_prefix (filename, "/usr/"))
|
||||||
{
|
{
|
||||||
g_autofree gchar *path = g_build_filename ("/var/run/host", alternate, NULL);
|
g_autofree gchar *path = g_build_filename ("/var/run/host", alternate, NULL);
|
||||||
bin_file = bin_file_new (path);
|
bin_file = bin_file_new (path, dirs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bin_file = bin_file_new (alternate);
|
bin_file = bin_file_new (alternate, dirs);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_hash_table_insert (self->bin_files, g_strdup (filename), bin_file);
|
g_hash_table_insert (self->bin_files, g_strdup (filename), bin_file);
|
||||||
@ -390,3 +416,27 @@ sysprof_elf_symbol_resolver_new (void)
|
|||||||
{
|
{
|
||||||
return g_object_new (SYSPROF_TYPE_ELF_SYMBOL_RESOLVER, NULL);
|
return g_object_new (SYSPROF_TYPE_ELF_SYMBOL_RESOLVER, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sysprof_elf_symbol_resolver_add_debug_dir (SysprofElfSymbolResolver *self,
|
||||||
|
const gchar *debug_dir)
|
||||||
|
{
|
||||||
|
gchar *val;
|
||||||
|
|
||||||
|
g_return_if_fail (SYSPROF_IS_ELF_SYMBOL_RESOLVER (self));
|
||||||
|
g_return_if_fail (debug_dir != NULL);
|
||||||
|
|
||||||
|
if (!g_file_test (debug_dir, G_FILE_TEST_EXISTS))
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (guint i = 0; i < self->debug_dirs->len; i++)
|
||||||
|
{
|
||||||
|
gchar * const *str = &g_array_index (self->debug_dirs, gchar *, i);
|
||||||
|
|
||||||
|
if (g_strcmp0 (*str, debug_dir) == 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
val = g_strdup (debug_dir);
|
||||||
|
g_array_append_val (self->debug_dirs, val);
|
||||||
|
}
|
||||||
|
|||||||
@ -37,14 +37,17 @@ G_DECLARE_FINAL_TYPE (SysprofElfSymbolResolver, sysprof_elf_symbol_resolver, SYS
|
|||||||
SYSPROF_AVAILABLE_IN_ALL
|
SYSPROF_AVAILABLE_IN_ALL
|
||||||
SysprofSymbolResolver *sysprof_elf_symbol_resolver_new (void);
|
SysprofSymbolResolver *sysprof_elf_symbol_resolver_new (void);
|
||||||
SYSPROF_AVAILABLE_IN_ALL
|
SYSPROF_AVAILABLE_IN_ALL
|
||||||
gboolean sysprof_elf_symbol_resolver_resolve_full (SysprofElfSymbolResolver *self,
|
void sysprof_elf_symbol_resolver_add_debug_dir (SysprofElfSymbolResolver *self,
|
||||||
guint64 time,
|
const gchar *debug_dir);
|
||||||
GPid pid,
|
SYSPROF_AVAILABLE_IN_ALL
|
||||||
SysprofAddressContext context,
|
gboolean sysprof_elf_symbol_resolver_resolve_full (SysprofElfSymbolResolver *self,
|
||||||
SysprofCaptureAddress address,
|
guint64 time,
|
||||||
SysprofCaptureAddress *begin,
|
GPid pid,
|
||||||
SysprofCaptureAddress *end,
|
SysprofAddressContext context,
|
||||||
gchar **name,
|
SysprofCaptureAddress address,
|
||||||
GQuark *tag);
|
SysprofCaptureAddress *begin,
|
||||||
|
SysprofCaptureAddress *end,
|
||||||
|
gchar **name,
|
||||||
|
GQuark *tag);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|||||||
Reference in New Issue
Block a user