From c0a7a94d5238351acdf525758b1216823c777355 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Thu, 6 Jul 2023 12:12:25 -0700 Subject: [PATCH] libsysprof-analyze: add flag to ignore system libraries --- src/libsysprof-analyze/sysprof-callgraph.c | 12 +++++- src/libsysprof-analyze/sysprof-callgraph.h | 5 ++- src/libsysprof-analyze/sysprof-elf.c | 35 +++++++++------- .../sysprof-symbol-private.h | 27 ++++++++++++ .../sysprof-callgraph-view-private.h | 1 + src/libsysprof-gtk/sysprof-callgraph-view.c | 41 +++++++++++++++++++ src/libsysprof-gtk/sysprof-callgraph-view.h | 27 +++++++----- src/libsysprof-gtk/tests/test-callgraph.c | 10 +++++ src/libsysprof-gtk/tests/test-tracks.ui | 5 +-- 9 files changed, 131 insertions(+), 32 deletions(-) diff --git a/src/libsysprof-analyze/sysprof-callgraph.c b/src/libsysprof-analyze/sysprof-callgraph.c index b6461dad..4af6ca0a 100644 --- a/src/libsysprof-analyze/sysprof-callgraph.c +++ b/src/libsysprof-analyze/sysprof-callgraph.c @@ -213,7 +213,8 @@ static SysprofCallgraphNode * sysprof_callgraph_add_trace (SysprofCallgraph *self, SysprofSymbol **symbols, guint n_symbols, - guint list_model_index) + guint list_model_index, + gboolean hide_system_libraries) { SysprofCallgraphNode *parent = NULL; @@ -238,6 +239,9 @@ sysprof_callgraph_add_trace (SysprofCallgraph *self, SysprofSymbol *symbol = symbols[i-1]; SysprofCallgraphNode *node = NULL; + if (hide_system_libraries && _sysprof_symbol_is_system_library (symbol)) + continue; + /* Try to find @symbol within the children of @parent */ for (SysprofCallgraphNode *iter = parent->children; iter != NULL; @@ -335,7 +339,11 @@ sysprof_callgraph_add_traceable (SysprofCallgraph *self, symbols[n_symbols++] = _sysprof_document_process_symbol (self->document, pid); symbols[n_symbols++] = everything; - node = sysprof_callgraph_add_trace (self, symbols, n_symbols, list_model_index); + node = sysprof_callgraph_add_trace (self, + symbols, + n_symbols, + list_model_index, + !!(self->flags & SYSPROF_CALLGRAPH_FLAGS_HIDE_SYSTEM_LIBRARIES)); if (node && self->augment_func) self->augment_func (self, diff --git a/src/libsysprof-analyze/sysprof-callgraph.h b/src/libsysprof-analyze/sysprof-callgraph.h index 4f476d31..6c77bd1e 100644 --- a/src/libsysprof-analyze/sysprof-callgraph.h +++ b/src/libsysprof-analyze/sysprof-callgraph.h @@ -64,8 +64,9 @@ typedef void (*SysprofAugmentationFunc) (SysprofCallgraph *callgraph, typedef enum _SysprofCallgraphFlags { - SYSPROF_CALLGRAPH_FLAGS_NONE = 0, - SYSPROF_CALLGRAPH_FLAGS_INCLUDE_THREADS = 1 << 1, + SYSPROF_CALLGRAPH_FLAGS_NONE = 0, + SYSPROF_CALLGRAPH_FLAGS_INCLUDE_THREADS = 1 << 1, + SYSPROF_CALLGRAPH_FLAGS_HIDE_SYSTEM_LIBRARIES = 1 << 2, } SysprofCallgraphFlags; SYSPROF_AVAILABLE_IN_ALL diff --git a/src/libsysprof-analyze/sysprof-elf.c b/src/libsysprof-analyze/sysprof-elf.c index 0a3a6bad..98b2b9b6 100644 --- a/src/libsysprof-analyze/sysprof-elf.c +++ b/src/libsysprof-analyze/sysprof-elf.c @@ -54,32 +54,18 @@ static const struct { const char *nick; } nick_table[] = { { "libc.so", "libc" }, - { "libcairo-gobject.so", "Cairo" }, - { "libcairo.so", "Cairo" }, - { "libclutter-1.0.so", "Clutter" }, - { "libclutter-glx-1.0.so", "Clutter" }, { "libffi.so", "libffi" }, - { "libgjs.so", "GJS" }, - { "libgstreamer-1-0.so", "GStreamer" }, - { "libgudev-1.0.so", "udev" }, - { "libibus-1.0.so", "IBus" }, - { "libinput.so", "Mutter" }, { "ld-linux-x86-64.so", "glibc" }, { "libnss_sss.so", "NSS" }, { "libsss_debug.so", "SSSD" }, { "libsss_util.so", "SSSD" }, { "libnss_systemd.so", "NSS" }, { "libpcre2-8.so", "PCRE" }, - { "libpixman-1.so", "Pixman" }, - { "libpolkit-agent-1.so", "PolicyKit" }, - { "libpolkit-gobject-1.so", "PolicyKit" }, { "libselinux.so", "SELinux" }, { "libssl3.so", "NSS" }, { "libstdc++.so", "libc" }, { "libsystemd.so", "systemd" }, { "libudev.so", "udev" }, - { "libvte-2.91.so", "VTE" }, - { "libvte-2.91-gtk4.so", "VTE" }, { "libxul.so", "XUL" }, { "libz.so", "Zlib" }, { "libzstd.so", "Zstd" }, @@ -90,6 +76,24 @@ static const struct { { "libgio-2.0.so", "Gio" }, { "libgirepository-1.0.so", "Introspection" }, + /* Cairo/Pixman */ + { "libcairo-gobject.so", "Cairo" }, + { "libcairo.so", "Cairo" }, + { "libpixman-1.so", "Pixman" }, + + /* Various GNOME Platform Libraries */ + { "libdex-1.so", "Dex" }, + { "libgjs.so", "GJS" }, + { "libgstreamer-1-0.so", "GStreamer" }, + { "libgudev-1.0.so", "udev" }, + { "libibus-1.0.so", "IBus" }, + { "libjson-glib-1.0.so", "JSON-GLib" }, + { "libjsonrpc-glib-1.0.so", "JSONRPC-GLib" }, + { "libpolkit-agent-1.so", "PolicyKit" }, + { "libpolkit-gobject-1.so", "PolicyKit" }, + { "libvte-2.91-gtk4.so", "VTE" }, + { "libvte-2.91.so", "VTE" }, + /* Pango and Harfbuzz */ { "libfribidi.so", "Fribidi" }, { "libpango-1.0.so", "Pango" }, @@ -122,6 +126,9 @@ static const struct { { "libwayland-server.so", "Wayland Server" }, /* Mutter/Clutter/Shell */ + { "libclutter-1.0.so", "Clutter" }, + { "libclutter-glx-1.0.so", "Clutter" }, + { "libinput.so", "libinput" }, { "libmutter-12.so", "Mutter" }, { "libmutter-cogl-12.so", "Mutter" }, { "libmutter-clutter-12.so", "Mutter" }, diff --git a/src/libsysprof-analyze/sysprof-symbol-private.h b/src/libsysprof-analyze/sysprof-symbol-private.h index 3f641ac4..545d9f48 100644 --- a/src/libsysprof-analyze/sysprof-symbol-private.h +++ b/src/libsysprof-analyze/sysprof-symbol-private.h @@ -85,4 +85,31 @@ _sysprof_symbol_is_context_switch (SysprofSymbol *symbol) return symbol->kind == SYSPROF_SYMBOL_KIND_CONTEXT_SWITCH; } +static inline gboolean +_sysprof_symbol_is_system_library (SysprofSymbol *symbol) +{ + switch (symbol->kind) + { + case SYSPROF_SYMBOL_KIND_ROOT: + case SYSPROF_SYMBOL_KIND_PROCESS: + case SYSPROF_SYMBOL_KIND_THREAD: + case SYSPROF_SYMBOL_KIND_CONTEXT_SWITCH: + case SYSPROF_SYMBOL_KIND_UNWINDABLE: + default: + return FALSE; + + case SYSPROF_SYMBOL_KIND_KERNEL: + return TRUE; + + case SYSPROF_SYMBOL_KIND_USER: + if (symbol->binary_nick != NULL) + return TRUE; + + if (symbol->binary_path != NULL) + return !!strstr (symbol->binary_path, "/usr/"); + + return FALSE; + } +} + G_END_DECLS diff --git a/src/libsysprof-gtk/sysprof-callgraph-view-private.h b/src/libsysprof-gtk/sysprof-callgraph-view-private.h index 55ce88b8..721f0aed 100644 --- a/src/libsysprof-gtk/sysprof-callgraph-view-private.h +++ b/src/libsysprof-gtk/sysprof-callgraph-view-private.h @@ -52,6 +52,7 @@ struct _SysprofCallgraphView guint reload_source; guint include_threads : 1; + guint hide_system_libraries : 1; }; struct _SysprofCallgraphViewClass diff --git a/src/libsysprof-gtk/sysprof-callgraph-view.c b/src/libsysprof-gtk/sysprof-callgraph-view.c index f66758c7..bca4ee3e 100644 --- a/src/libsysprof-gtk/sysprof-callgraph-view.c +++ b/src/libsysprof-gtk/sysprof-callgraph-view.c @@ -31,6 +31,7 @@ enum { PROP_0, PROP_CALLGRAPH, PROP_DOCUMENT, + PROP_HIDE_SYSTEM_LIBRARIES, PROP_INCLUDE_THREADS, PROP_TRACEABLES, N_PROPS @@ -385,6 +386,10 @@ sysprof_callgraph_view_get_property (GObject *object, g_value_set_object (value, sysprof_callgraph_view_get_document (self)); break; + case PROP_HIDE_SYSTEM_LIBRARIES: + g_value_set_boolean (value, sysprof_callgraph_view_get_hide_system_libraries (self)); + break; + case PROP_INCLUDE_THREADS: g_value_set_boolean (value, sysprof_callgraph_view_get_include_threads (self)); break; @@ -412,6 +417,10 @@ sysprof_callgraph_view_set_property (GObject *object, sysprof_callgraph_view_set_document (self, g_value_get_object (value)); break; + case PROP_HIDE_SYSTEM_LIBRARIES: + sysprof_callgraph_view_set_hide_system_libraries (self, g_value_get_boolean (value)); + break; + case PROP_INCLUDE_THREADS: sysprof_callgraph_view_set_include_threads (self, g_value_get_boolean (value)); break; @@ -445,6 +454,11 @@ sysprof_callgraph_view_class_init (SysprofCallgraphViewClass *klass) SYSPROF_TYPE_DOCUMENT, (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + properties[PROP_HIDE_SYSTEM_LIBRARIES] = + g_param_spec_boolean ("hide-system-libraries", NULL, NULL, + FALSE, + (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + properties[PROP_INCLUDE_THREADS] = g_param_spec_boolean ("include-threads", NULL, NULL, FALSE, @@ -590,6 +604,9 @@ sysprof_callgraph_view_reload (SysprofCallgraphView *self) if (self->include_threads) flags |= SYSPROF_CALLGRAPH_FLAGS_INCLUDE_THREADS; + if (self->hide_system_libraries) + flags |= SYSPROF_CALLGRAPH_FLAGS_HIDE_SYSTEM_LIBRARIES; + sysprof_document_callgraph_async (self->document, flags, self->traceables, @@ -724,6 +741,30 @@ sysprof_callgraph_view_get_callgraph (SysprofCallgraphView *self) return self->callgraph; } +gboolean +sysprof_callgraph_view_get_hide_system_libraries (SysprofCallgraphView *self) +{ + g_return_val_if_fail (SYSPROF_IS_CALLGRAPH_VIEW (self), FALSE); + + return self->hide_system_libraries; +} + +void +sysprof_callgraph_view_set_hide_system_libraries (SysprofCallgraphView *self, + gboolean hide_system_libraries) +{ + g_return_if_fail (SYSPROF_IS_CALLGRAPH_VIEW (self)); + + hide_system_libraries = !!hide_system_libraries; + + if (self->hide_system_libraries != hide_system_libraries) + { + self->hide_system_libraries = hide_system_libraries; + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_HIDE_SYSTEM_LIBRARIES]); + sysprof_callgraph_view_queue_reload (self); + } +} + gboolean sysprof_callgraph_view_get_include_threads (SysprofCallgraphView *self) { diff --git a/src/libsysprof-gtk/sysprof-callgraph-view.h b/src/libsysprof-gtk/sysprof-callgraph-view.h index 0d6074fe..596ae1ab 100644 --- a/src/libsysprof-gtk/sysprof-callgraph-view.h +++ b/src/libsysprof-gtk/sysprof-callgraph-view.h @@ -36,24 +36,29 @@ typedef struct _SysprofCallgraphView SysprofCallgraphView; typedef struct _SysprofCallgraphViewClass SysprofCallgraphViewClass; SYSPROF_AVAILABLE_IN_ALL -GType sysprof_callgraph_view_get_type (void) G_GNUC_CONST; +GType sysprof_callgraph_view_get_type (void) G_GNUC_CONST; SYSPROF_AVAILABLE_IN_ALL -SysprofCallgraph *sysprof_callgraph_view_get_callgraph (SysprofCallgraphView *self); +SysprofCallgraph *sysprof_callgraph_view_get_callgraph (SysprofCallgraphView *self); SYSPROF_AVAILABLE_IN_ALL -SysprofDocument *sysprof_callgraph_view_get_document (SysprofCallgraphView *self); +SysprofDocument *sysprof_callgraph_view_get_document (SysprofCallgraphView *self); SYSPROF_AVAILABLE_IN_ALL -void sysprof_callgraph_view_set_document (SysprofCallgraphView *self, - SysprofDocument *document); +void sysprof_callgraph_view_set_document (SysprofCallgraphView *self, + SysprofDocument *document); SYSPROF_AVAILABLE_IN_ALL -GListModel *sysprof_callgraph_view_get_traceables (SysprofCallgraphView *self); +GListModel *sysprof_callgraph_view_get_traceables (SysprofCallgraphView *self); SYSPROF_AVAILABLE_IN_ALL -void sysprof_callgraph_view_set_traceables (SysprofCallgraphView *self, - GListModel *model); +void sysprof_callgraph_view_set_traceables (SysprofCallgraphView *self, + GListModel *model); SYSPROF_AVAILABLE_IN_ALL -gboolean sysprof_callgraph_view_get_include_threads (SysprofCallgraphView *self); +gboolean sysprof_callgraph_view_get_include_threads (SysprofCallgraphView *self); SYSPROF_AVAILABLE_IN_ALL -void sysprof_callgraph_view_set_include_threads (SysprofCallgraphView *self, - gboolean include_threads); +void sysprof_callgraph_view_set_include_threads (SysprofCallgraphView *self, + gboolean include_threads); +SYSPROF_AVAILABLE_IN_ALL +gboolean sysprof_callgraph_view_get_hide_system_libraries (SysprofCallgraphView *self); +SYSPROF_AVAILABLE_IN_ALL +void sysprof_callgraph_view_set_hide_system_libraries (SysprofCallgraphView *self, + gboolean hide_system_libraries); G_DEFINE_AUTOPTR_CLEANUP_FUNC (SysprofCallgraphView, g_object_unref) diff --git a/src/libsysprof-gtk/tests/test-callgraph.c b/src/libsysprof-gtk/tests/test-callgraph.c index dc6b71bb..ab50b68a 100644 --- a/src/libsysprof-gtk/tests/test-callgraph.c +++ b/src/libsysprof-gtk/tests/test-callgraph.c @@ -29,9 +29,11 @@ static GMainLoop *main_loop; static char *kallsyms_path; static char *filename; static gboolean include_threads; +static gboolean hide_system_libraries; static const GOptionEntry entries[] = { { "kallsyms", 'k', 0, G_OPTION_ARG_FILENAME, &kallsyms_path, "The path to kallsyms to use for decoding", "PATH" }, { "threads", 't', 0, G_OPTION_ARG_NONE, &include_threads, "Include threads in the callgraph" }, + { "hide-system-libraries", 's', 0, G_OPTION_ARG_NONE, &hide_system_libraries, "Hide system libraries in the callgraph" }, { 0 } }; @@ -73,6 +75,7 @@ main (int argc, GtkWidget *progress; GtkWidget *message; GtkWidget *threads; + GtkWidget *system_libs; GtkWindow *window; sysprof_clock_init (); @@ -134,8 +137,14 @@ main (int argc, "active", include_threads, NULL); gtk_box_append (GTK_BOX (hbox), threads); + gtk_box_append (GTK_BOX (hbox), gtk_label_new ("Hide System Libraries")); + system_libs = g_object_new (GTK_TYPE_SWITCH, + "active", hide_system_libraries, + NULL); + gtk_box_append (GTK_BOX (hbox), system_libs); view = g_object_new (SYSPROF_TYPE_WEIGHTED_CALLGRAPH_VIEW, "include-threads", include_threads, + "hide-system-libraries", hide_system_libraries, "vexpand", TRUE, NULL); gtk_box_append (GTK_BOX (box), GTK_WIDGET (view)); @@ -159,6 +168,7 @@ main (int argc, gtk_window_present (window); g_object_bind_property (threads, "active", view, "include-threads", 0); + g_object_bind_property (system_libs, "active", view, "hide-system-libraries", 0); g_object_bind_property (loader, "message", message, "label", 0); g_object_bind_property (loader, "fraction", progress, "fraction", 0); diff --git a/src/libsysprof-gtk/tests/test-tracks.ui b/src/libsysprof-gtk/tests/test-tracks.ui index 2607a0a9..0c9bce12 100644 --- a/src/libsysprof-gtk/tests/test-tracks.ui +++ b/src/libsysprof-gtk/tests/test-tracks.ui @@ -187,9 +187,8 @@
Callgraph - - Show Threads - + Show Threads + Show System Libraries