From 530aff1d50e298e1dc56a127a5764db3bbf98f42 Mon Sep 17 00:00:00 2001 From: varun-r-mallya Date: Sat, 15 Feb 2025 02:13:56 +0530 Subject: [PATCH 1/6] sysprof-greeter: replicate UI for managing debug directories with wrong key Signed-off-by: varun-r-mallya --- src/sysprof/sysprof-greeter.c | 159 ++++++++++++++++++++++++++++++++- src/sysprof/sysprof-greeter.ui | 44 +++++++++ 2 files changed, 202 insertions(+), 1 deletion(-) diff --git a/src/sysprof/sysprof-greeter.c b/src/sysprof/sysprof-greeter.c index 5f44cb60..5203f38e 100644 --- a/src/sysprof/sysprof-greeter.c +++ b/src/sysprof/sysprof-greeter.c @@ -42,12 +42,14 @@ struct _SysprofGreeter AdwWindow parent_instance; GtkStringList *envvars; + GtkStringList *debugdirs; SysprofRecordingTemplate *recording_template; AdwViewStack *view_stack; GtkListBox *sidebar_list_box; AdwPreferencesPage *record_page; GtkListBox *app_environment; + GtkListBox *debug_directories; GtkSwitch *sample_native_stacks; GtkSwitch *sample_javascript_stacks; GtkSwitch *record_disk_usage; @@ -109,6 +111,20 @@ on_env_items_changed_cb (SysprofGreeter *self, g_list_model_get_n_items (model) > 0); } +static void +on_debug_dir_items_changed_cb (SysprofGreeter *self, + guint position, + guint removed, + guint added, + GListModel *model) +{ + g_assert (SYSPROF_IS_GREETER (self)); + g_assert (G_IS_LIST_MODEL (model)); + + gtk_widget_set_visible (GTK_WIDGET (self->debug_directories), + g_list_model_get_n_items (model) > 0); +} + static void on_env_entry_changed_cb (SysprofGreeter *self, SysprofEntryPopover *popover) @@ -155,6 +171,52 @@ failure: sysprof_entry_popover_set_message (popover, errstr); } +static void +on_debug_dir_entry_changed_cb (SysprofGreeter *self, + SysprofEntryPopover *popover) +{ + const char *errstr = NULL; + gboolean valid = FALSE; + const char *text; + const char *eq; + + g_assert (SYSPROF_IS_GREETER (self)); + g_assert (SYSPROF_IS_ENTRY_POPOVER (popover)); + + text = sysprof_entry_popover_get_text (popover); + eq = strchr (text, '='); + + if (!str_empty0 (text) && eq == NULL) + errstr = _("Use KEY=VALUE to set an environment variable"); + + if (eq != NULL && eq != text) + { + if (g_unichar_isdigit (g_utf8_get_char (text))) + { + errstr = _("Keys may not start with a number"); + goto failure; + + } + for (const char *iter = text; iter < eq; iter = g_utf8_next_char (iter)) + { + gunichar ch = g_utf8_get_char (iter); + + if (!g_unichar_isalnum (ch) && ch != '_') + { + errstr = _("Keys may only contain alpha-numerics or underline."); + goto failure; + } + } + + if (g_ascii_isalpha (*text)) + valid = TRUE; + } + +failure: + sysprof_entry_popover_set_ready (popover, valid); + sysprof_entry_popover_set_message (popover, errstr); +} + static void on_env_entry_activate_cb (SysprofGreeter *self, const char *text, @@ -168,6 +230,19 @@ on_env_entry_activate_cb (SysprofGreeter *self, sysprof_entry_popover_set_text (popover, ""); } +static void +on_debug_dir_entry_activate_cb (SysprofGreeter *self, + const char *text, + SysprofEntryPopover *popover) +{ + g_assert (SYSPROF_IS_GREETER (self)); + g_assert (SYSPROF_IS_ENTRY_POPOVER (popover)); + g_assert (GTK_IS_STRING_LIST (self->debugdirs)); + + gtk_string_list_append (self->debugdirs, text); + sysprof_entry_popover_set_text (popover, ""); +} + static void sysprof_greeter_record_cb (GObject *object, GAsyncResult *result, @@ -453,6 +528,31 @@ delete_envvar_cb (SysprofGreeter *self, } } +static void +delete_debugdirs_cb (SysprofGreeter *self, + GtkButton *button) +{ + const char *debugdirs; + guint n_items; + + g_assert (SYSPROF_IS_GREETER (self)); + g_assert (GTK_IS_BUTTON (button)); + + debugdirs = g_object_get_data (G_OBJECT (button), "DEBUGDIR"); + n_items = g_list_model_get_n_items (G_LIST_MODEL (self->debugdirs)); + + for (guint i = 0; i < n_items; i++) + { + g_autoptr(GtkStringObject) str = g_list_model_get_item (G_LIST_MODEL (self->debugdirs), i); + + if (g_strcmp0 (debugdirs, gtk_string_object_get_string (str)) == 0) + { + gtk_string_list_remove (self->debugdirs, i); + break; + } + } +} + static GtkWidget * create_envvar_row_cb (gpointer item, gpointer user_data) @@ -493,6 +593,46 @@ create_envvar_row_cb (gpointer item, return GTK_WIDGET (row); } +static GtkWidget * +create_debugdirs_row_cb (gpointer item, + gpointer user_data) +{ + SysprofGreeter *self = user_data; + GtkStringObject *obj = item; + const char *str; + g_autofree char *markup = NULL; + g_autofree char *escaped = NULL; + AdwActionRow *row; + GtkButton *button; + + g_assert (SYSPROF_IS_GREETER (self)); + g_assert (GTK_IS_STRING_OBJECT (obj)); + + str = gtk_string_object_get_string (obj); + escaped = g_markup_escape_text (str, -1); + markup = g_strdup_printf ("%s", escaped); + row = g_object_new (ADW_TYPE_ACTION_ROW, + "title", markup, + "title-selectable", TRUE, + NULL); + button = g_object_new (GTK_TYPE_BUTTON, + "icon-name", "list-remove-symbolic", + "css-classes", STRV_INIT ("flat", "circular"), + "valign", GTK_ALIGN_CENTER, + NULL); + g_object_set_data_full (G_OBJECT (button), + "DEBUGDIR", + g_strdup (str), + g_free); + g_signal_connect_object (button, + "clicked", + G_CALLBACK (delete_debugdirs_cb), + self, + G_CONNECT_SWAPPED); + adw_action_row_add_suffix (row, GTK_WIDGET (button)); + + return GTK_WIDGET (row); +} static char * translate_power_profile (GtkStringObject *strobj) @@ -542,6 +682,7 @@ sysprof_greeter_dispose (GObject *object) gtk_widget_dispose_template (GTK_WIDGET (self), SYSPROF_TYPE_GREETER); g_clear_object (&self->envvars); + g_clear_object (&self->debugdirs); g_clear_object (&self->recording_template); G_OBJECT_CLASS (sysprof_greeter_parent_class)->dispose (object); @@ -558,9 +699,11 @@ sysprof_greeter_class_init (SysprofGreeterClass *klass) gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/sysprof/sysprof-greeter.ui"); gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, app_environment); + gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, debug_directories); gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, bundle_symbols); gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, debuginfod); gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, envvars); + gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, debugdirs); gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, power_combo); gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, record_compositor); gtk_widget_class_bind_template_child (widget_class, SysprofGreeter, record_disk_usage); @@ -582,6 +725,8 @@ sysprof_greeter_class_init (SysprofGreeterClass *klass) gtk_widget_class_bind_template_callback (widget_class, get_file_path); gtk_widget_class_bind_template_callback (widget_class, on_env_entry_activate_cb); gtk_widget_class_bind_template_callback (widget_class, on_env_entry_changed_cb); + gtk_widget_class_bind_template_callback (widget_class, on_debug_dir_entry_changed_cb); + gtk_widget_class_bind_template_callback (widget_class, on_debug_dir_entry_activate_cb); gtk_widget_class_bind_template_callback (widget_class, translate_power_profile); gtk_widget_class_install_action (widget_class, "win.record-to-memory", NULL, sysprof_greeter_record_to_memory_action); @@ -614,6 +759,13 @@ sysprof_greeter_init (SysprofGreeter *self) G_CONNECT_SWAPPED); on_env_items_changed_cb (self, 0, 0, 0, G_LIST_MODEL (self->envvars)); + g_signal_connect_object (self->debugdirs, + "items-changed", + G_CALLBACK (on_debug_dir_items_changed_cb), + self, + G_CONNECT_SWAPPED); + on_debug_dir_items_changed_cb (self, 0, 0, 0, G_LIST_MODEL (self->debugdirs)); + gtk_list_box_bind_model (self->sidebar_list_box, G_LIST_MODEL (adw_view_stack_get_pages (self->view_stack)), sysprof_greeter_create_sidebar_row, @@ -622,7 +774,12 @@ sysprof_greeter_init (SysprofGreeter *self) gtk_list_box_bind_model (self->app_environment, G_LIST_MODEL (self->envvars), create_envvar_row_cb, - self, NULL); + self, NULL); + + gtk_list_box_bind_model (self->debug_directories, + G_LIST_MODEL (self->debugdirs), + create_debugdirs_row_cb, + self, NULL); if (self->recording_template) { diff --git a/src/sysprof/sysprof-greeter.ui b/src/sysprof/sysprof-greeter.ui index e69e2658..32ae3ce2 100644 --- a/src/sysprof/sysprof-greeter.ui +++ b/src/sysprof/sysprof-greeter.ui @@ -636,6 +636,48 @@ + + + + + Debug File Directories + Directories to search for debug files + + + + + 12 + none + false + + + + + + left + 12 + end + + + Add _Directory + true + + + + + Add Directory + _Add + 400 + + + + + + + + @@ -706,6 +748,8 @@ + + From db914e8c63f78ad760ccad8806099eb77ab1b64f Mon Sep 17 00:00:00 2001 From: varun-r-mallya Date: Sat, 15 Feb 2025 02:39:49 +0530 Subject: [PATCH 2/6] sysprof-greeter: validate directory existence in debug directory entry Signed-off-by: varun-r-mallya --- src/sysprof/sysprof-greeter.c | 46 ++++++++++------------------------- 1 file changed, 13 insertions(+), 33 deletions(-) diff --git a/src/sysprof/sysprof-greeter.c b/src/sysprof/sysprof-greeter.c index 5203f38e..a817e751 100644 --- a/src/sysprof/sysprof-greeter.c +++ b/src/sysprof/sysprof-greeter.c @@ -175,42 +175,22 @@ static void on_debug_dir_entry_changed_cb (SysprofGreeter *self, SysprofEntryPopover *popover) { - const char *errstr = NULL; - gboolean valid = FALSE; - const char *text; - const char *eq; +const char *errstr = NULL; +gboolean valid = FALSE; +const char *text; - g_assert (SYSPROF_IS_GREETER (self)); - g_assert (SYSPROF_IS_ENTRY_POPOVER (popover)); +g_assert (SYSPROF_IS_GREETER (self)); +g_assert (SYSPROF_IS_ENTRY_POPOVER (popover)); - text = sysprof_entry_popover_get_text (popover); - eq = strchr (text, '='); +text = sysprof_entry_popover_get_text (popover); - if (!str_empty0 (text) && eq == NULL) - errstr = _("Use KEY=VALUE to set an environment variable"); - - if (eq != NULL && eq != text) - { - if (g_unichar_isdigit (g_utf8_get_char (text))) - { - errstr = _("Keys may not start with a number"); - goto failure; - - } - for (const char *iter = text; iter < eq; iter = g_utf8_next_char (iter)) - { - gunichar ch = g_utf8_get_char (iter); - - if (!g_unichar_isalnum (ch) && ch != '_') - { - errstr = _("Keys may only contain alpha-numerics or underline."); - goto failure; - } - } - - if (g_ascii_isalpha (*text)) - valid = TRUE; - } +if (g_file_test (text, G_FILE_TEST_IS_DIR)) + valid = TRUE; +else + { + errstr = _("Directory does not exist"); + goto failure; + } failure: sysprof_entry_popover_set_ready (popover, valid); From 78c6a5ad4969582bba00fbeaa817d70fcaf2be82 Mon Sep 17 00:00:00 2001 From: varun-r-mallya Date: Sun, 16 Feb 2025 04:15:25 +0530 Subject: [PATCH 3/6] sysprof-recording-template: add debugdirs property for external debug directories Signed-off-by: varun-r-mallya --- src/sysprof/sysprof-recording-template.c | 25 +++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/sysprof/sysprof-recording-template.c b/src/sysprof/sysprof-recording-template.c index 3d7646de..ea01e094 100644 --- a/src/sysprof/sysprof-recording-template.c +++ b/src/sysprof/sysprof-recording-template.c @@ -35,6 +35,7 @@ struct _SysprofRecordingTemplate char *cwd; char *power_profile; char **environ; + char **debugdirs; guint stack_size; @@ -65,6 +66,7 @@ enum { PROP_BATTERY_CHARGE, PROP_BUNDLE_SYMBOLS, PROP_DEBUGINFOD, + PROP_DEBUGDIRS, PROP_CLEAR_ENVIRON, PROP_COMMAND_LINE, PROP_CPU_USAGE, @@ -103,6 +105,7 @@ sysprof_recording_template_finalize (GObject *object) g_clear_pointer (&self->cwd, g_free); g_clear_pointer (&self->power_profile, g_free); g_clear_pointer (&self->environ, g_free); + g_clear_pointer (&self->debugdirs, g_free); G_OBJECT_CLASS (sysprof_recording_template_parent_class)->finalize (object); } @@ -156,6 +159,10 @@ sysprof_recording_template_get_property (GObject *object, case PROP_ENVIRON: g_value_set_boxed (value, self->environ); break; + + case PROP_DEBUGDIRS: + g_value_set_boxed (value, self->debugdirs); + break; case PROP_FRAME_TIMINGS: g_value_set_boolean (value, self->frame_timings); @@ -272,6 +279,11 @@ sysprof_recording_template_set_property (GObject *object, g_clear_pointer (&self->environ, g_strfreev); self->environ = g_value_dup_boxed (value); break; + + case PROP_DEBUGDIRS: + g_clear_pointer (&self->debugdirs, g_strfreev); + self->environ = g_value_dup_boxed (value); + break; case PROP_FRAME_TIMINGS: self->frame_timings = g_value_get_boolean (value); @@ -396,6 +408,11 @@ sysprof_recording_template_class_init (SysprofRecordingTemplateClass *klass) g_param_spec_boxed ("environ", NULL, NULL, G_TYPE_STRV, (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + properties[PROP_DEBUGDIRS] = + g_param_spec_boxed ("debugdirs", NULL, NULL, + G_TYPE_STRV, + (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); properties[PROP_FRAME_TIMINGS] = g_param_spec_boolean ("frame-timings", NULL, NULL, @@ -783,9 +800,11 @@ sysprof_recording_template_create_loader (SysprofRecordingTemplate *self, multi = sysprof_multi_symbolizer_new (); elf = SYSPROF_ELF_SYMBOLIZER (sysprof_elf_symbolizer_new ()); - /* TODO: add extra-debug-directories property and use that to - * call sysprof_elf_symbolizer_set_external_debug_dirs(elf,...) - */ + + if (self->debugdirs) + { + sysprof_elf_symbolizer_set_external_debug_dirs (elf, (const char * const *)self->debugdirs); + } /* Add in order of priority */ sysprof_multi_symbolizer_take (multi, sysprof_bundled_symbolizer_new ()); From 6424bd35aa72d2edc2fd28779300d41c16f7177e Mon Sep 17 00:00:00 2001 From: varun-r-mallya Date: Thu, 20 Feb 2025 09:43:08 +0530 Subject: [PATCH 4/6] sysprof-greeter: improve code quality and UI in greeter Signed-off-by: varun-r-mallya --- src/sysprof/sysprof-greeter.c | 20 +++++++------------- src/sysprof/sysprof-greeter.ui | 16 ++++++++-------- src/sysprof/sysprof-recording-template.c | 6 ++---- 3 files changed, 17 insertions(+), 25 deletions(-) diff --git a/src/sysprof/sysprof-greeter.c b/src/sysprof/sysprof-greeter.c index a817e751..2b424a90 100644 --- a/src/sysprof/sysprof-greeter.c +++ b/src/sysprof/sysprof-greeter.c @@ -175,24 +175,18 @@ static void on_debug_dir_entry_changed_cb (SysprofGreeter *self, SysprofEntryPopover *popover) { -const char *errstr = NULL; -gboolean valid = FALSE; -const char *text; + const char *errstr = NULL; + gboolean valid = FALSE; + const char *text; -g_assert (SYSPROF_IS_GREETER (self)); -g_assert (SYSPROF_IS_ENTRY_POPOVER (popover)); + g_assert (SYSPROF_IS_GREETER (self)); + g_assert (SYSPROF_IS_ENTRY_POPOVER (popover)); -text = sysprof_entry_popover_get_text (popover); + text = sysprof_entry_popover_get_text (popover); -if (g_file_test (text, G_FILE_TEST_IS_DIR)) - valid = TRUE; -else - { + if (!(valid = g_file_test (text, G_FILE_TEST_IS_DIR))) errstr = _("Directory does not exist"); - goto failure; - } -failure: sysprof_entry_popover_set_ready (popover, valid); sysprof_entry_popover_set_message (popover, errstr); } diff --git a/src/sysprof/sysprof-greeter.ui b/src/sysprof/sysprof-greeter.ui index 32ae3ce2..5af1dcc5 100644 --- a/src/sysprof/sysprof-greeter.ui +++ b/src/sysprof/sysprof-greeter.ui @@ -638,12 +638,8 @@ - - - Debug File Directories - Directories to search for debug files - - + Debug File Directories + Directories to search for debug files 12 @@ -656,9 +652,13 @@ - left + + up 12 - end + center Add _Directory diff --git a/src/sysprof/sysprof-recording-template.c b/src/sysprof/sysprof-recording-template.c index ea01e094..cd0afa6c 100644 --- a/src/sysprof/sysprof-recording-template.c +++ b/src/sysprof/sysprof-recording-template.c @@ -105,7 +105,7 @@ sysprof_recording_template_finalize (GObject *object) g_clear_pointer (&self->cwd, g_free); g_clear_pointer (&self->power_profile, g_free); g_clear_pointer (&self->environ, g_free); - g_clear_pointer (&self->debugdirs, g_free); + g_clear_pointer (&self->debugdirs, g_strfreev); G_OBJECT_CLASS (sysprof_recording_template_parent_class)->finalize (object); } @@ -802,9 +802,7 @@ sysprof_recording_template_create_loader (SysprofRecordingTemplate *self, elf = SYSPROF_ELF_SYMBOLIZER (sysprof_elf_symbolizer_new ()); if (self->debugdirs) - { - sysprof_elf_symbolizer_set_external_debug_dirs (elf, (const char * const *)self->debugdirs); - } + sysprof_elf_symbolizer_set_external_debug_dirs (elf, (const char * const *)self->debugdirs); /* Add in order of priority */ sysprof_multi_symbolizer_take (multi, sysprof_bundled_symbolizer_new ()); From 0c406167dc45fd6f14c1eb4084942d459bbb9552 Mon Sep 17 00:00:00 2001 From: varun-r-mallya Date: Wed, 26 Feb 2025 02:12:20 +0530 Subject: [PATCH 5/6] sysprof-greeter: add debug directory handling in profiler creation Signed-off-by: varun-r-mallya --- src/sysprof/sysprof-greeter.c | 26 +++++++++++++++++++++--- src/sysprof/sysprof-recording-template.c | 2 +- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/sysprof/sysprof-greeter.c b/src/sysprof/sysprof-greeter.c index 2b424a90..00b8a767 100644 --- a/src/sysprof/sysprof-greeter.c +++ b/src/sysprof/sysprof-greeter.c @@ -254,6 +254,9 @@ sysprof_greeter_create_profiler (SysprofGreeter *self, g_autoptr(GFile) dir = NULL; GtkStringObject *strobj; const char *str; + guint n_items; + g_autoptr(GStrvBuilder) builder = NULL; + g_autofree GStrv debugdirs = NULL; g_assert (SYSPROF_IS_GREETER (self)); @@ -281,6 +284,23 @@ sysprof_greeter_create_profiler (SysprofGreeter *self, "power-profile", str, NULL); + if ((n_items = g_list_model_get_n_items (G_LIST_MODEL (self->debugdirs)))) + { + builder = g_strv_builder_new (); + + for (guint i = 0; i < n_items; i++) + { + strobj = g_list_model_get_item (G_LIST_MODEL (self->debugdirs), i); + g_strv_builder_add (builder, gtk_string_object_get_string (strobj)); + } + + debugdirs = g_strv_builder_end (builder); + + g_object_set (self->recording_template, + "debugdirs", debugdirs, + NULL); + } + if (!(profiler = sysprof_recording_template_apply (self->recording_template, error))) return NULL; @@ -506,20 +526,20 @@ static void delete_debugdirs_cb (SysprofGreeter *self, GtkButton *button) { - const char *debugdirs; + const char *debug_directory; guint n_items; g_assert (SYSPROF_IS_GREETER (self)); g_assert (GTK_IS_BUTTON (button)); - debugdirs = g_object_get_data (G_OBJECT (button), "DEBUGDIR"); + debug_directory = g_object_get_data (G_OBJECT (button), "DEBUGDIR"); n_items = g_list_model_get_n_items (G_LIST_MODEL (self->debugdirs)); for (guint i = 0; i < n_items; i++) { g_autoptr(GtkStringObject) str = g_list_model_get_item (G_LIST_MODEL (self->debugdirs), i); - if (g_strcmp0 (debugdirs, gtk_string_object_get_string (str)) == 0) + if (g_strcmp0 (debug_directory, gtk_string_object_get_string (str)) == 0) { gtk_string_list_remove (self->debugdirs, i); break; diff --git a/src/sysprof/sysprof-recording-template.c b/src/sysprof/sysprof-recording-template.c index cd0afa6c..8b93b684 100644 --- a/src/sysprof/sysprof-recording-template.c +++ b/src/sysprof/sysprof-recording-template.c @@ -282,7 +282,7 @@ sysprof_recording_template_set_property (GObject *object, case PROP_DEBUGDIRS: g_clear_pointer (&self->debugdirs, g_strfreev); - self->environ = g_value_dup_boxed (value); + self->debugdirs = g_value_dup_boxed (value); break; case PROP_FRAME_TIMINGS: From 50036d26fd97128c93cb8933de2d9c61418f4ed0 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Thu, 20 Mar 2025 13:01:29 -0700 Subject: [PATCH 6/6] sysprof/greeter: fixup g_auto usage and trailing space --- src/sysprof/sysprof-greeter.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sysprof/sysprof-greeter.c b/src/sysprof/sysprof-greeter.c index 00b8a767..dc48c2d1 100644 --- a/src/sysprof/sysprof-greeter.c +++ b/src/sysprof/sysprof-greeter.c @@ -123,7 +123,7 @@ on_debug_dir_items_changed_cb (SysprofGreeter *self, gtk_widget_set_visible (GTK_WIDGET (self->debug_directories), g_list_model_get_n_items (model) > 0); -} +} static void on_env_entry_changed_cb (SysprofGreeter *self, @@ -256,7 +256,7 @@ sysprof_greeter_create_profiler (SysprofGreeter *self, const char *str; guint n_items; g_autoptr(GStrvBuilder) builder = NULL; - g_autofree GStrv debugdirs = NULL; + g_auto(GStrv) debugdirs = NULL; g_assert (SYSPROF_IS_GREETER (self)); @@ -768,12 +768,12 @@ sysprof_greeter_init (SysprofGreeter *self) gtk_list_box_bind_model (self->app_environment, G_LIST_MODEL (self->envvars), create_envvar_row_cb, - self, NULL); + self, NULL); gtk_list_box_bind_model (self->debug_directories, G_LIST_MODEL (self->debugdirs), create_debugdirs_row_cb, - self, NULL); + self, NULL); if (self->recording_template) {