mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
libsysprof: add summary information for memprof profile
This commit is contained in:
@ -62,6 +62,11 @@ typedef struct
|
||||
GtkRadioButton *summary;
|
||||
GtkRadioButton *all_allocs;
|
||||
GtkRadioButton *temp_allocs;
|
||||
GtkLabel *temp_allocs_count;
|
||||
GtkLabel *num_allocs;
|
||||
GtkLabel *leaked_allocs;
|
||||
GtkLabel *peak_allocs;
|
||||
GtkListBox *by_size;
|
||||
|
||||
GCancellable *cancellable;
|
||||
|
||||
@ -160,6 +165,117 @@ build_functions_store (StackNode *node,
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
update_summary (SysprofMemprofPage *self,
|
||||
SysprofMemprofProfile *profile)
|
||||
{
|
||||
SysprofMemprofPagePrivate *priv = sysprof_memprof_page_get_instance_private (self);
|
||||
SysprofMemprofStats stats;
|
||||
g_autoptr(GString) str = NULL;
|
||||
|
||||
g_assert (SYSPROF_IS_MEMPROF_PAGE (self));
|
||||
g_assert (SYSPROF_IS_MEMPROF_PROFILE (profile));
|
||||
|
||||
sysprof_memprof_profile_get_stats (profile, &stats);
|
||||
|
||||
str = g_string_new (NULL);
|
||||
|
||||
g_string_append_printf (str, "%"G_GINT64_FORMAT, stats.n_allocs);
|
||||
gtk_label_set_label (priv->num_allocs, str->str);
|
||||
g_string_truncate (str, 0);
|
||||
|
||||
g_string_append_printf (str, "%"G_GINT64_FORMAT, stats.leaked_allocs);
|
||||
gtk_label_set_label (priv->leaked_allocs, str->str);
|
||||
g_string_truncate (str, 0);
|
||||
|
||||
g_string_append_printf (str, "%"G_GINT64_FORMAT, stats.temp_allocs);
|
||||
gtk_label_set_label (priv->temp_allocs_count, str->str);
|
||||
g_string_truncate (str, 0);
|
||||
|
||||
gtk_container_foreach (GTK_CONTAINER (priv->by_size),
|
||||
(GtkCallback)gtk_widget_destroy,
|
||||
NULL);
|
||||
|
||||
for (guint i = 0; i < G_N_ELEMENTS (stats.by_size); i++)
|
||||
{
|
||||
g_autofree gchar *prevstr = NULL;
|
||||
g_autofree gchar *sizestr = NULL;
|
||||
g_autofree gchar *title_str = NULL;
|
||||
g_autofree gchar *subtitle_str = NULL;
|
||||
g_autofree gchar *allocstr = NULL;
|
||||
g_autofree gchar *tempstr = NULL;
|
||||
g_autofree gchar *leakedstr = NULL;
|
||||
g_autofree gchar *allstr = NULL;
|
||||
GtkWidget *row;
|
||||
GtkWidget *title;
|
||||
GtkWidget *subtitle;
|
||||
GtkWidget *prog;
|
||||
GtkWidget *box;
|
||||
|
||||
if (stats.by_size[i].n_allocs == 0)
|
||||
continue;
|
||||
|
||||
row = gtk_list_box_row_new ();
|
||||
title = gtk_label_new (NULL);
|
||||
subtitle = gtk_label_new (NULL);
|
||||
prog = gtk_level_bar_new_for_interval (0, stats.n_allocs);
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
|
||||
|
||||
sizestr = g_format_size_full (stats.by_size[i].bucket, G_FORMAT_SIZE_IEC_UNITS);
|
||||
if (i == 0)
|
||||
{
|
||||
title_str = g_strdup_printf ("≤ %s", sizestr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* translators: %s is replaced with a memory size such as "32 bytes" */
|
||||
prevstr = g_format_size_full (stats.by_size[i-1].bucket, G_FORMAT_SIZE_IEC_UNITS);
|
||||
/* translators: %s is replaced with the the lower and upper bound memory sizes in bytes */
|
||||
title_str = g_strdup_printf (_("> %s to %s"), prevstr, sizestr);
|
||||
}
|
||||
|
||||
gtk_label_set_label (GTK_LABEL (title), title_str);
|
||||
gtk_label_set_xalign (GTK_LABEL (title), 0);
|
||||
dzl_gtk_widget_add_style_class (title, "dim-label");
|
||||
|
||||
gtk_widget_set_margin_start (box, 6);
|
||||
gtk_widget_set_margin_end (box, 6);
|
||||
|
||||
gtk_widget_set_margin_top (prog, 1);
|
||||
gtk_widget_set_margin_bottom (prog, 1);
|
||||
|
||||
allocstr = g_strdup_printf ("%"G_GINT64_FORMAT, stats.by_size[i].n_allocs);
|
||||
tempstr = g_strdup_printf ("%"G_GINT64_FORMAT, stats.by_size[i].temp_allocs);
|
||||
allstr = g_format_size_full (stats.by_size[i].allocated,
|
||||
G_FORMAT_SIZE_IEC_UNITS);
|
||||
subtitle_str = g_strdup_printf ("%s allocations, %s temporary, %s",
|
||||
allocstr, tempstr, allstr);
|
||||
|
||||
gtk_label_set_label (GTK_LABEL (subtitle), subtitle_str);
|
||||
gtk_label_set_xalign (GTK_LABEL (subtitle), 0);
|
||||
|
||||
#if 0
|
||||
/* TODO: Make this chunked by [temp][rest]... */
|
||||
gtk_level_bar_add_offset_value (GTK_LEVEL_BAR (prog),
|
||||
GTK_LEVEL_BAR_OFFSET_HIGH,
|
||||
stats.by_size[i].temp_allocs);
|
||||
gtk_level_bar_add_offset_value (GTK_LEVEL_BAR (prog),
|
||||
GTK_LEVEL_BAR_OFFSET_LOW,
|
||||
stats.by_size[i].n_allocs);
|
||||
#endif
|
||||
gtk_level_bar_set_value (GTK_LEVEL_BAR (prog),
|
||||
stats.by_size[i].n_allocs);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (row), box);
|
||||
gtk_container_add (GTK_CONTAINER (box), title);
|
||||
gtk_container_add (GTK_CONTAINER (box), prog);
|
||||
gtk_container_add (GTK_CONTAINER (box), subtitle);
|
||||
gtk_container_add (GTK_CONTAINER (priv->by_size), row);
|
||||
|
||||
gtk_widget_show_all (row);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_memprof_page_load (SysprofMemprofPage *self,
|
||||
SysprofMemprofProfile *profile)
|
||||
@ -189,8 +305,13 @@ sysprof_memprof_page_load (SysprofMemprofPage *self,
|
||||
if (!g_set_object (&priv->profile, profile))
|
||||
return;
|
||||
|
||||
update_summary (self, profile);
|
||||
|
||||
if (sysprof_memprof_profile_is_empty (profile))
|
||||
return;
|
||||
{
|
||||
gtk_stack_set_visible_child_name (priv->stack, "summary");
|
||||
return;
|
||||
}
|
||||
|
||||
stash = sysprof_memprof_profile_get_stash (profile);
|
||||
|
||||
@ -802,7 +923,6 @@ sysprof_memprof_page_generate_cb (GObject *object,
|
||||
{
|
||||
SysprofProfile *profile = (SysprofProfile *)object;
|
||||
SysprofMemprofPage *self;
|
||||
SysprofMemprofPagePrivate *priv;
|
||||
g_autoptr(GTask) task = user_data;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
@ -811,15 +931,11 @@ sysprof_memprof_page_generate_cb (GObject *object,
|
||||
g_assert (G_IS_TASK (task));
|
||||
|
||||
self = g_task_get_source_object (task);
|
||||
priv = sysprof_memprof_page_get_instance_private (self);
|
||||
|
||||
if (!sysprof_profile_generate_finish (profile, result, &error))
|
||||
g_task_return_error (task, g_error_copy (error));
|
||||
else
|
||||
sysprof_memprof_page_set_profile (self, SYSPROF_MEMPROF_PROFILE (profile));
|
||||
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
gtk_stack_set_visible_child_name (priv->stack, "callgraph");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -876,19 +992,6 @@ sysprof_memprof_page_load_finish (SysprofPage *page,
|
||||
return g_task_propagate_boolean (G_TASK (result), error);
|
||||
}
|
||||
|
||||
static void
|
||||
do_summary (SysprofMemprofPage *self)
|
||||
{
|
||||
#if 0
|
||||
SysprofMemprofPagePrivate *priv = sysprof_memprof_page_get_instance_private (self);
|
||||
|
||||
g_assert (SYSPROF_IS_MEMPROF_PAGE (self));
|
||||
|
||||
g_cancellable_cancel (priv->cancellable);
|
||||
gtk_stack_set_visible_child_name (priv->stack, "summary");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
do_allocs (SysprofMemprofPage *self,
|
||||
SysprofMemprofMode mode)
|
||||
@ -914,7 +1017,7 @@ mode_notify_active (SysprofMemprofPage *self,
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
|
||||
{
|
||||
if (button == priv->summary)
|
||||
do_summary (self);
|
||||
do_allocs (self, SYSPROF_MEMPROF_MODE_SUMMARY);
|
||||
else if (button == priv->all_allocs)
|
||||
do_allocs (self, SYSPROF_MEMPROF_MODE_ALL_ALLOCS);
|
||||
else if (button == priv->temp_allocs)
|
||||
@ -922,6 +1025,19 @@ mode_notify_active (SysprofMemprofPage *self,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sep_header_func (GtkListBoxRow *row,
|
||||
GtkListBoxRow *before,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (before != NULL)
|
||||
gtk_list_box_row_set_header (row,
|
||||
g_object_new (GTK_TYPE_SEPARATOR,
|
||||
"orientation", GTK_ORIENTATION_HORIZONTAL,
|
||||
"visible", TRUE,
|
||||
NULL));
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_memprof_page_finalize (GObject *object)
|
||||
{
|
||||
@ -1010,6 +1126,7 @@ sysprof_memprof_page_class_init (SysprofMemprofPageClass *klass)
|
||||
gtk_widget_class_set_template_from_resource (widget_class,
|
||||
"/org/gnome/sysprof/ui/sysprof-memprof-page.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofMemprofPage, by_size);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofMemprofPage, callers_view);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofMemprofPage, function_size_cell);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofMemprofPage, function_size_column);
|
||||
@ -1020,6 +1137,10 @@ sysprof_memprof_page_class_init (SysprofMemprofPageClass *klass)
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofMemprofPage, all_allocs);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofMemprofPage, temp_allocs);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofMemprofPage, summary);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofMemprofPage, temp_allocs_count);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofMemprofPage, num_allocs);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofMemprofPage, leaked_allocs);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, SysprofMemprofPage, peak_allocs);
|
||||
|
||||
bindings = gtk_binding_set_by_class (klass);
|
||||
gtk_binding_entry_add_signal (bindings, GDK_KEY_Left, GDK_MOD1_MASK, "go-previous", 0);
|
||||
@ -1042,6 +1163,8 @@ sysprof_memprof_page_init (SysprofMemprofPage *self)
|
||||
|
||||
gtk_stack_set_visible_child_name (priv->stack, "empty-state");
|
||||
|
||||
gtk_list_box_set_header_func (priv->by_size, sep_header_func, NULL, NULL);
|
||||
|
||||
g_signal_connect_object (priv->all_allocs,
|
||||
"notify::active",
|
||||
G_CALLBACK (mode_notify_active),
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
<object class="GtkRadioButton" id="summary">
|
||||
<property name="label" translatable="yes">Summary</property>
|
||||
<property name="draw-indicator">false</property>
|
||||
<property name="visible">false</property>
|
||||
<property name="visible">true</property>
|
||||
<property name="active">false</property>
|
||||
</object>
|
||||
</child>
|
||||
@ -57,6 +57,160 @@
|
||||
<child>
|
||||
<object class="GtkStack" id="stack">
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="margin">16</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="DzlThreeGrid">
|
||||
<property name="expand">true</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<property name="column-spacing">18</property>
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Peak Allocation</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="visible">false</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">left</property>
|
||||
<property name="row">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="peak_allocs">
|
||||
<property name="xalign">0</property>
|
||||
<property name="selectable">true</property>
|
||||
<property name="visible">false</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Number of Allocations</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="visible">true</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">left</property>
|
||||
<property name="row">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="num_allocs">
|
||||
<property name="xalign">0</property>
|
||||
<property name="selectable">true</property>
|
||||
<property name="visible">true</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Leaked Allocations</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="visible">false</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">left</property>
|
||||
<property name="row">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="leaked_allocs">
|
||||
<property name="xalign">0</property>
|
||||
<property name="selectable">true</property>
|
||||
<property name="visible">false</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Temporary Allocations</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="visible">true</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">left</property>
|
||||
<property name="row">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="temp_allocs_count">
|
||||
<property name="xalign">0</property>
|
||||
<property name="selectable">true</property>
|
||||
<property name="width-chars">50</property>
|
||||
<property name="visible">true</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Allocations by Size</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">start</property>
|
||||
<property name="visible">true</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">left</property>
|
||||
<property name="row">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<property name="visible">true</property>
|
||||
<child>
|
||||
<object class="GtkListBox" id="by_size">
|
||||
<property name="visible">true</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="column">center</property>
|
||||
<property name="row">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">summary</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkPaned">
|
||||
<property name="orientation">horizontal</property>
|
||||
@ -265,8 +419,8 @@
|
||||
<child>
|
||||
<object class="DzlEmptyState">
|
||||
<property name="icon-name">content-loading-symbolic</property>
|
||||
<property name="title" translatable="yes">Generating Callgraph</property>
|
||||
<property name="subtitle" translatable="yes">Sysprof is busy creating the selected callgraph.</property>
|
||||
<property name="title" translatable="yes">Analyzing Memory Allocations</property>
|
||||
<property name="subtitle" translatable="yes">Sysprof is busy analyzing memory allocations.</property>
|
||||
<property name="visible">true</property>
|
||||
</object>
|
||||
<packing>
|
||||
|
||||
Reference in New Issue
Block a user