Web lists-archives.com

Need help in debugging glib crash


I'm trying to debug issue with recent glib (2.43.4) on OpenIndiana.
The problems started after updating from glib 2.28 to glib 2.43. Sometimes different applications (for example, thunderbird) dies in g_type_check_instance_cast.

I've investigated Thunderbird crash and found the following.
TB creates several G_FILE_MONITOR objects . Then dispose some of them. Later it can register and emit signals to already disposed monitors.

I used the following patch to log some debug info:

diff -ur glib-2.43.4-fm-debug/gio/fen/gfenfilemonitor.c glib-2.43.4/gio/fen/gfenfilemonitor.c --- glib-2.43.4-fm-debug/gio/fen/gfenfilemonitor.c 2015-05-19 11:55:07.948864217 +0300 +++ glib-2.43.4/gio/fen/gfenfilemonitor.c 2015-05-19 11:56:20.256640332 +0300
@@ -128,6 +128,7 @@
     GFenFileMonitor *self = G_FEN_FILE_MONITOR (monitor);

+    printf("Canceling monitor %X\n",monitor);
     if (self->enabled) {
         fen_remove (G_LOCAL_FILE_MONITOR (self)->filename, self, FALSE);
         self->enabled = FALSE;
diff -ur glib-2.43.4-fm-debug/gio/gfilemonitor.c glib-2.43.4/gio/gfilemonitor.c
--- glib-2.43.4/gio/gfilemonitor.c.~1~  2014-12-20 00:49:48.000000000 +0300
+++ glib-2.43.4/gio/gfilemonitor.c      2015-05-19 16:18:44.293651778 +0300
@@ -196,8 +196,11 @@
   monitor = G_FILE_MONITOR (object);
   priv = monitor->priv;

+  printf("Disposing monitor %x\n", monitor);
   if (priv->pending_file_change_source)
+      printf("Clearing pending file changes on monitor %x\n", monitor);
       g_source_destroy (priv->pending_file_change_source);
       g_source_unref (priv->pending_file_change_source);
       priv->pending_file_change_source = NULL;
@@ -278,6 +281,7 @@
 static void
 g_file_monitor_init (GFileMonitor *monitor)
+  printf("Initializing monitor %x\n", monitor);
   monitor->priv = g_file_monitor_get_instance_private (monitor);
   monitor->priv->rate_limit_msec = DEFAULT_RATE_LIMIT_MSECS;
monitor->priv->rate_limiter = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal,
@@ -383,9 +387,12 @@
 static gboolean
 emit_cb (gpointer data)
-  GFileMonitor *monitor = G_FILE_MONITOR (data);
+  GFileMonitor *monitor;
   GSList *pending, *iter;

+  printf("emit_cb: data=%x\n",data);
+  monitor = G_FILE_MONITOR (data);
+  printf("after calling G_FILE_MONITOR(%x)\n",monitor);
   g_mutex_lock (&monitor->priv->mutex);
   pending = g_slist_reverse (monitor->priv->pending_file_changes);
   monitor->priv->pending_file_changes = NULL;
@@ -442,6 +449,7 @@
       /* We don't ref monitor here - instead dispose will free any
        * pending idles.
+      printf("Setting callback on monitor %x\n", monitor);
       g_source_set_callback (source, emit_cb, monitor, NULL);
       g_source_set_name (source, "[gio] emit_cb");
       g_source_attach (source, monitor->priv->context);

And I was able to get the following log before crash:

$ grep a69c0d8 /tmp/log.1
Initializing monitor a69c0d8
Setting callback on monitor a69c0d8
emit_cb: data=a69c0d8
after calling G_FILE_MONITOR(a69c0d8)
Disposing monitor a69c0d8
Setting callback on monitor a69c0d8
emit_cb: data=a69c0d8

Here the program crashed.
So, we see that emit_in_idle() was called after entering to g_file_monitor_dispose() function, which if I understand this correctly lead to crash. Perhaps, some additional handling is necessary in g_file_monitor_dispose() so that we don't try to emit signal to "disposing" object ? Do you have some thoughts on how to debug further and fix this issue?

С уважением,
Александр Пыхалов,
программист отдела телекоммуникационной инфраструктуры
управления информационно-коммуникационной инфраструктуры ЮФУ
gtk-devel-list mailing list