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.
This commit is contained in:
Christian Hergert
2023-06-12 16:41:30 -07:00
parent b3bd853168
commit ddfa3f57ab
3 changed files with 98 additions and 27 deletions

View File

@ -49,6 +49,8 @@
#include "line-reader-private.h" #include "line-reader-private.h"
#define MAX_STACK_DEPTH 128
struct _SysprofDocument struct _SysprofDocument
{ {
GObject parent_instance; GObject parent_instance;
@ -1303,3 +1305,51 @@ sysprof_document_get_clock_at_start (SysprofDocument *self)
return self->header.time; 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);
}

View File

@ -56,6 +56,9 @@ GListModel *sysprof_document_list_jitmaps (SysprofDocument
SYSPROF_AVAILABLE_IN_ALL SYSPROF_AVAILABLE_IN_ALL
GListModel *sysprof_document_list_counters (SysprofDocument *self); GListModel *sysprof_document_list_counters (SysprofDocument *self);
SYSPROF_AVAILABLE_IN_ALL SYSPROF_AVAILABLE_IN_ALL
GListModel *sysprof_document_list_symbols_in_traceable (SysprofDocument *self,
SysprofDocumentTraceable *traceable);
SYSPROF_AVAILABLE_IN_ALL
guint sysprof_document_symbolize_traceable (SysprofDocument *self, guint sysprof_document_symbolize_traceable (SysprofDocument *self,
SysprofDocumentTraceable *traceable, SysprofDocumentTraceable *traceable,
SysprofSymbol **symbols, SysprofSymbol **symbols,

View File

@ -50,6 +50,24 @@ SysprofSymbol *_sysprof_symbol_new (GRefString *name,
SysprofAddress begin_address, SysprofAddress begin_address,
SysprofAddress end_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 static inline gboolean
_sysprof_symbol_equal (const SysprofSymbol *a, _sysprof_symbol_equal (const SysprofSymbol *a,
const SysprofSymbol *b) const SysprofSymbol *b)