Re: Is gtkmm deleting stuff it shouldn't be deleting ??



On 06/11/2013 10:01, Kjell Ahlstedt wrote:
I've made some tests on a Linux system (Ubuntu 13.10) with gtk+ 2.24.22 and gtkmm 2.24.4 from tarballs, glib and glibmm fairly new versions from git's master branch. I get the same sequence of calls as you get, but no crash. gtk_widget_dispose() is called after gtk_widget_unrealize() in both cases. valgrind does not report any accesses to freed memory.

I'll make some more tests. It would be nice if I could reproduce the crash or some similar misbehaviour. I wonder if gtk+ behaves differently on Windows and Linux systems.


Thanks Kjell,

Literally within the last few minutes I've discovered the exact cause of the crash. Although it showed all the hallmarks of a "double deletion" somewhere, I gradually became convinced that it was something more subtle. Last time, I mentioned that I'd traced the crash as far as line 3065 of gtkwidget.c:-

On 05/11/2013 10:10, John Emmas wrote:

      g_signal_emit (widget, widget_signals[UNREALIZE], 0);


As you can probably imagine, the crash occurs in the handler for UNREALIZE. Unfortunately the handler is fearsomely convoluted but eventually it ends up in 'gtk_widget_real_unrealize()' which calls 'gtk_selection_remove_all()'. That seems to remove some things called 'current_retrievals' and 'current_selections' (whatever they are) and it ends up calling 'gtk_selection_target_list_remove()'. This calls 'g_object_get_data()' which ends up in 'g_datalist_get_data()' which looks like this:-

    gpointer
    g_datalist_get_data (GData     **datalist,
                     const gchar *key)
        {
          gpointer res = NULL;
          GData *d;
          GDataElt *data, *data_end;

          g_return_val_if_fail (datalist != NULL, NULL);

          g_datalist_lock (datalist);

          d = G_DATALIST_GET_POINTER (datalist);
          if (d)
          {
              data = d->data;
              data_end = data + d->len;
              while (data < data_end)
            {
if (strcmp (g_quark_to_string (data->key), key) == 0) // <--- NOTE THIS LINE
                {
                  res = data->data;
                  break;
                }
              data++;
            }
          }

          g_datalist_unlock (datalist);

          return res;
        }

NOTE THE MARKED LINE - 'g_quark_to_string()' gets called and its return value is compared (in this case) to the string "gtk-selection-handlers*. But 'g_quark_to_string()' can return NULL. Here's what it looks like:-

    const gchar *
    g_quark_to_string (GQuark quark)
        {
          gchar* result = NULL;
          gchar **strings;
          gint seq_id;

          seq_id = g_atomic_int_get (&quark_seq_id);
          strings = g_atomic_pointer_get (&quarks);

          if (quark < seq_id)
            result = strings[quark];

          return result;
        }

Going back to where it gets called.... on the final iteration around the 'while' loop, 'data->key' appears to have an uninitialized value. This causes 'g_quark_to_string()' to return NULL, which crashes strcmp(). This is all way above my comfort level with GTK. I've no idea what data-key represents or whether there's some valid reason why it might be uninitialized - BUT - on my particular system its value happens to be a very high number. If it had been zero (or any low number) this problem would probably go unnoticed.

Hope one of you guys can make sense of this.

John
P.S. If I appear to be slow in responding please forgive me. At my end, the gtkmm mailing list is very variable. Sometimes postings get sent to me straight away. Other times they can take a day or more to reach me!!



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]