From ddfa3f57ab9d6ad0d35758efe31ed6616b90ba81 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Mon, 12 Jun 2023 16:41:30 -0700 Subject: [PATCH] libsysprof-analyze: add sysprof_document_list_symbols_in_traceable() This function will list the symbols in a traceable in a way that is suitable for showing in a GtkListView or GtkColumnView. For example, that requires creating copies of the symbols so that duplicates do not cause hickups with GtkListItemManager. --- src/libsysprof-analyze/sysprof-document.c | 50 ++++++++++++++++ src/libsysprof-analyze/sysprof-document.h | 57 ++++++++++--------- .../sysprof-symbol-private.h | 18 ++++++ 3 files changed, 98 insertions(+), 27 deletions(-) diff --git a/src/libsysprof-analyze/sysprof-document.c b/src/libsysprof-analyze/sysprof-document.c index a18b1134..6903d337 100644 --- a/src/libsysprof-analyze/sysprof-document.c +++ b/src/libsysprof-analyze/sysprof-document.c @@ -49,6 +49,8 @@ #include "line-reader-private.h" +#define MAX_STACK_DEPTH 128 + struct _SysprofDocument { GObject parent_instance; @@ -1303,3 +1305,51 @@ sysprof_document_get_clock_at_start (SysprofDocument *self) return self->header.time; } + +/** + * sysprof_document_list_symbols_in_traceable: + * @self: a #SysprofDocument + * @traceable: a #SysprofDocumentTraceable + * + * Gets the symbols in @traceable as a list model. + * + * Returns: (transfer full): a #GListModel of #SysprofSymbol + */ +GListModel * +sysprof_document_list_symbols_in_traceable (SysprofDocument *self, + SysprofDocumentTraceable *traceable) +{ + SysprofAddressContext final_context; + GListStore *ret = NULL; + SysprofSymbol **symbols; + guint stack_depth; + guint n_symbols; + + g_return_val_if_fail (SYSPROF_IS_DOCUMENT (self), NULL); + g_return_val_if_fail (SYSPROF_IS_DOCUMENT_TRACEABLE (traceable), NULL); + + ret = g_list_store_new (SYSPROF_TYPE_SYMBOL); + + stack_depth = MIN (MAX_STACK_DEPTH, sysprof_document_traceable_get_stack_depth (traceable)); + symbols = g_alloca (sizeof (SysprofSymbol *) * stack_depth); + n_symbols = sysprof_document_symbolize_traceable (self, traceable, symbols, stack_depth, &final_context); + + if (n_symbols > 0 && symbols[0]->is_context_switch) + { + symbols++; + n_symbols--; + } + + /* We must make a copy of the symbols because GtkListViewBase does not + * deal with the same object being in a list gracefully. Realistically + * we should deal with this there, but this gets things moving forward + * for the time being. + */ + for (guint i = 0; i < n_symbols; i++) + { + g_autoptr(SysprofSymbol) copy = _sysprof_symbol_copy (symbols[i]); + g_list_store_append (ret, copy); + } + + return G_LIST_MODEL (ret); +} diff --git a/src/libsysprof-analyze/sysprof-document.h b/src/libsysprof-analyze/sysprof-document.h index fe87ae4d..735c7450 100644 --- a/src/libsysprof-analyze/sysprof-document.h +++ b/src/libsysprof-analyze/sysprof-document.h @@ -37,43 +37,46 @@ SYSPROF_AVAILABLE_IN_ALL G_DECLARE_FINAL_TYPE (SysprofDocument, sysprof_document, SYSPROF, DOCUMENT, GObject) SYSPROF_AVAILABLE_IN_ALL -gint64 sysprof_document_get_clock_at_start (SysprofDocument *self); +gint64 sysprof_document_get_clock_at_start (SysprofDocument *self); SYSPROF_AVAILABLE_IN_ALL -SysprofDocumentFile *sysprof_document_lookup_file (SysprofDocument *self, - const char *path); +SysprofDocumentFile *sysprof_document_lookup_file (SysprofDocument *self, + const char *path); SYSPROF_AVAILABLE_IN_ALL -GListModel *sysprof_document_list_files (SysprofDocument *self); +GListModel *sysprof_document_list_files (SysprofDocument *self); SYSPROF_AVAILABLE_IN_ALL -GListModel *sysprof_document_list_traceables (SysprofDocument *self); +GListModel *sysprof_document_list_traceables (SysprofDocument *self); SYSPROF_AVAILABLE_IN_ALL -GListModel *sysprof_document_list_allocations (SysprofDocument *self); +GListModel *sysprof_document_list_allocations (SysprofDocument *self); SYSPROF_AVAILABLE_IN_ALL -GListModel *sysprof_document_list_samples (SysprofDocument *self); +GListModel *sysprof_document_list_samples (SysprofDocument *self); SYSPROF_AVAILABLE_IN_ALL -GListModel *sysprof_document_list_processes (SysprofDocument *self); +GListModel *sysprof_document_list_processes (SysprofDocument *self); SYSPROF_AVAILABLE_IN_ALL -GListModel *sysprof_document_list_jitmaps (SysprofDocument *self); +GListModel *sysprof_document_list_jitmaps (SysprofDocument *self); SYSPROF_AVAILABLE_IN_ALL -GListModel *sysprof_document_list_counters (SysprofDocument *self); +GListModel *sysprof_document_list_counters (SysprofDocument *self); SYSPROF_AVAILABLE_IN_ALL -guint sysprof_document_symbolize_traceable (SysprofDocument *self, - SysprofDocumentTraceable *traceable, - SysprofSymbol **symbols, - guint n_symbols, - SysprofAddressContext *final_context); +GListModel *sysprof_document_list_symbols_in_traceable (SysprofDocument *self, + SysprofDocumentTraceable *traceable); SYSPROF_AVAILABLE_IN_ALL -void sysprof_document_callgraph_async (SysprofDocument *self, - GListModel *traceables, - gsize augment_size, - SysprofAugmentationFunc augment_func, - gpointer augment_func_data, - GDestroyNotify augment_func_data_destroy, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); +guint sysprof_document_symbolize_traceable (SysprofDocument *self, + SysprofDocumentTraceable *traceable, + SysprofSymbol **symbols, + guint n_symbols, + SysprofAddressContext *final_context); SYSPROF_AVAILABLE_IN_ALL -SysprofCallgraph *sysprof_document_callgraph_finish (SysprofDocument *self, - GAsyncResult *result, - GError **error); +void sysprof_document_callgraph_async (SysprofDocument *self, + GListModel *traceables, + gsize augment_size, + SysprofAugmentationFunc augment_func, + gpointer augment_func_data, + GDestroyNotify augment_func_data_destroy, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +SYSPROF_AVAILABLE_IN_ALL +SysprofCallgraph *sysprof_document_callgraph_finish (SysprofDocument *self, + GAsyncResult *result, + GError **error); G_END_DECLS diff --git a/src/libsysprof-analyze/sysprof-symbol-private.h b/src/libsysprof-analyze/sysprof-symbol-private.h index 35e61e0c..bedbf047 100644 --- a/src/libsysprof-analyze/sysprof-symbol-private.h +++ b/src/libsysprof-analyze/sysprof-symbol-private.h @@ -50,6 +50,24 @@ SysprofSymbol *_sysprof_symbol_new (GRefString *name, SysprofAddress begin_address, SysprofAddress end_address); +static inline SysprofSymbol * +_sysprof_symbol_copy (SysprofSymbol *self) +{ + SysprofSymbol *copy; + + copy = _sysprof_symbol_new (self->name ? g_ref_string_acquire (self->name) : NULL, + self->binary_path ? g_ref_string_acquire (self->binary_path) : NULL, + self->binary_nick ? g_ref_string_acquire (self->binary_nick) : NULL, + self->begin_address, + self->end_address); + copy->is_context_switch = self->is_context_switch; + copy->is_everything = self->is_everything; + copy->is_untraceable = self->is_untraceable; + copy->is_process = self->is_process; + + return copy; +} + static inline gboolean _sysprof_symbol_equal (const SysprofSymbol *a, const SysprofSymbol *b)