libsysprof-gtk: reinit after removing item from set

Otherwise we risk accessing bits inside the structure that were freed.
This commit is contained in:
Christian Hergert
2023-06-26 17:43:28 -07:00
parent 40b4ff4a36
commit 15dcbbc948

View File

@ -41,6 +41,8 @@ struct _SysprofNormalizedSeries
gulong range_changed_handler; gulong range_changed_handler;
guint update_source; guint update_source;
guint disposed : 1;
}; };
struct _SysprofNormalizedSeriesClass struct _SysprofNormalizedSeriesClass
@ -64,6 +66,7 @@ static gboolean
sysprof_normalized_series_update_missing (gpointer user_data) sysprof_normalized_series_update_missing (gpointer user_data)
{ {
SysprofNormalizedSeries *self = user_data; SysprofNormalizedSeries *self = user_data;
g_autoptr(GtkExpression) expression = NULL;
g_autoptr(GListModel) model = NULL; g_autoptr(GListModel) model = NULL;
g_autoptr(EggBitset) bitset = NULL; g_autoptr(EggBitset) bitset = NULL;
EggBitsetIter iter; EggBitsetIter iter;
@ -71,14 +74,15 @@ sysprof_normalized_series_update_missing (gpointer user_data)
g_assert (SYSPROF_IS_NORMALIZED_SERIES (self)); g_assert (SYSPROF_IS_NORMALIZED_SERIES (self));
if (self->missing == NULL) if (self->missing == NULL || self->disposed)
{ {
self->update_source = 0; self->update_source = 0;
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
} }
model = g_object_ref (sysprof_series_get_model (self->series));
bitset = egg_bitset_ref (self->missing); bitset = egg_bitset_ref (self->missing);
model = g_object_ref (sysprof_series_get_model (self->series));
expression = gtk_expression_ref (self->expression);
if (egg_bitset_iter_init_first (&iter, bitset, &position)) if (egg_bitset_iter_init_first (&iter, bitset, &position))
{ {
@ -87,20 +91,23 @@ sysprof_normalized_series_update_missing (gpointer user_data)
for (;;) for (;;)
{ {
GObject *item = g_list_model_get_item (model, position); g_autoptr(GObject) item = g_list_model_get_item (model, position);
GValue value = G_VALUE_INIT; g_auto(GValue) value = G_VALUE_INIT;
guint next; guint next = GTK_INVALID_LIST_POSITION;
gtk_expression_evaluate (self->expression, item, &value); gtk_expression_evaluate (expression, item, &value);
g_assert (self->values->len > position);
g_array_index (self->values, float, position) = _sysprof_axis_normalize (self->axis, &value); g_array_index (self->values, float, position) = _sysprof_axis_normalize (self->axis, &value);
egg_bitset_remove (bitset, position); egg_bitset_remove (bitset, position);
g_value_unset (&value); if (self->disposed)
g_clear_object (&item); break;
if (!egg_bitset_iter_next (&iter, &next) || next != position + 1) if (!egg_bitset_iter_init_first (&iter, bitset, &next) ||
next != position + 1)
{ {
g_list_model_items_changed (G_LIST_MODEL (self), g_list_model_items_changed (G_LIST_MODEL (self),
first, first,
@ -109,7 +116,8 @@ sysprof_normalized_series_update_missing (gpointer user_data)
first = next; first = next;
} }
if (g_get_monotonic_time () >= deadline) if (next == GTK_INVALID_LIST_POSITION ||
g_get_monotonic_time () >= deadline)
break; break;
position = next; position = next;
@ -132,7 +140,7 @@ sysprof_normalized_series_maybe_update (SysprofNormalizedSeries *self)
g_assert (SYSPROF_IS_NORMALIZED_SERIES (self)); g_assert (SYSPROF_IS_NORMALIZED_SERIES (self));
if (self->update_source) if (self->update_source || self->disposed)
return; return;
if (!self->missing || egg_bitset_is_empty (self->missing)) if (!self->missing || egg_bitset_is_empty (self->missing))
@ -231,6 +239,8 @@ sysprof_normalized_series_dispose (GObject *object)
{ {
SysprofNormalizedSeries *self = (SysprofNormalizedSeries *)object; SysprofNormalizedSeries *self = (SysprofNormalizedSeries *)object;
self->disposed = TRUE;
g_clear_handle_id (&self->update_source, g_source_remove); g_clear_handle_id (&self->update_source, g_source_remove);
g_clear_signal_handler (&self->range_changed_handler, self->axis); g_clear_signal_handler (&self->range_changed_handler, self->axis);
@ -239,8 +249,6 @@ sysprof_normalized_series_dispose (GObject *object)
g_clear_pointer (&self->expression, gtk_expression_unref); g_clear_pointer (&self->expression, gtk_expression_unref);
egg_bitset_remove_all (self->missing);
G_OBJECT_CLASS (sysprof_normalized_series_parent_class)->dispose (object); G_OBJECT_CLASS (sysprof_normalized_series_parent_class)->dispose (object);
} }