Re: Gee Problem with TreeMap



On Mon, 2013-11-11 at 17:07 -0600, Daniel Espinosa wrote:
Please tell me what is wrong!!!!

I'm using a TreeMap as a container inside a class that need to be
subclassed from other.


My problem is when I try to run my program fails to try get values and
its key.

Running under valgrind with G_DEBUG=fatal-warnings,always-malloc it
looks like the object are freed prematurely:

==2710== Invalid read of size 8
==2710==    at 0x5119580: g_type_check_instance_cast
(in /usr/lib64/libgobject-2.0.so.0.3800.1)
==2710==    by 0x403243: app_main (test.c:749)
==2710==    by 0x4033DF: main (test.c:772)
==2710==  Address 0x5e577f0 is 32 bytes inside a block of size 72 free'd
==2710==    at 0x4C2B0EC: free
(in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==2710==    by 0x51183B2: g_type_free_instance
(in /usr/lib64/libgobject-2.0.so.0.3800.1)
==2710==    by 0x402F83: app_main (test.c:697)
==2710==    by 0x4033DF: main (test.c:772)

Digging into the problem (breaking at test.c:697) it looks like the V is
not set properly for the iterator:

(gdb) p *((GeeTreeMapValueIterator *) _tmp21_)->priv 
$6 = {k_type = 64, k_dup_func = 0x401630 <g_strdup plt>, 
  k_destroy_func = 0x401390 <g_free plt>, v_type = 0, v_dup_func = 0x0, 
  v_destroy_func = 0x0}

It's because they are not set correctly for the map:

(gdb) p *u->priv->map->priv 
$11 = {k_type = 64, k_dup_func = 0x401630 <g_strdup plt>, 
  k_destroy_func = 0x401390 <g_free plt>, v_type = 0, v_dup_func = 0x0, 
  v_destroy_func = 0x0, 
  _key_compare_func = 0x7ffff7b639f0
<____lambda25__gcompare_data_func>, 
  _key_compare_func_target = 0x0, 
  _key_compare_func_target_destroy_notify = 0x0, 
  _value_equal_func = 0x7ffff7b63800
<______lambda24__gee_equal_data_func>, 
  _value_equal_func_target = 0x0, 
  _value_equal_func_target_destroy_notify = 0x0, _size = 2, _keys =
0x0, 
  _values = 0x0, _entries = 0x0, root = 0x614c80, first = 0x614c40, 
  last = 0x614c80, stamp = 2}

Strangely it is despite that in Manager is set correctly:

(gdb) p *u->priv->map->priv 
$11 = {k_type = 64, k_dup_func = 0x401630 <g_strdup plt>, 
  k_destroy_func = 0x401390 <g_free plt>, v_type = 0, v_dup_func = 0x0, 
  v_destroy_func = 0x0, 
  _key_compare_func = 0x7ffff7b639f0
<____lambda25__gcompare_data_func>, 
  _key_compare_func_target = 0x0, 
  _key_compare_func_target_destroy_notify = 0x0, 
  _value_equal_func = 0x7ffff7b63800
<______lambda24__gee_equal_data_func>, 
  _value_equal_func_target = 0x0, 
  _value_equal_func_target_destroy_notify = 0x0, _size = 2, _keys =
0x0, 
  _values = 0x0, _entries = 0x0, root = 0x614c80, first = 0x614c40, 
  last = 0x614c80, stamp = 2}

Breaking at manager_instance_init it shows that it is because u->priv is
not yet initialized:

(gdb) p *self->priv
$17 = {v_type = 0, v_dup_func = 0x0, v_destroy_func = 0x0, map = 0x0}

So yes - the bug is that private structure is initialized before the
generics are initialized. In fact the generics are initialized at the
end of _construct.

A quick workaround would be to change:

private Gee.TreeMap<string,V> map = new Gee.TreeMap<string,V> ();

to:

private Gee.TreeMap<string,V> map;
Manager () {
    map = new Gee.TreeMap<string,V> ();
}

But you probably should fill a bug about it (I guess the quick solution
in Vala would be just to move construction to _construct/_new but I'm
not certain how backward compatible it is).

Maciej



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