Vala: Invalid read when a joined thread gets unreferenced

215 views Asked by At

When I compile and run the code below in valgrind, it looks like the thread gets free'd when I join the thread, and then later when it gets unreferenced some memory that is already free'd gets read.

Is this a "false positive" from valgrind? If not, is it in general safe to ignore in larger parallel programs? How do I get around it?

int main (string[] args) {
    Thread<int> thread = new Thread<int>.try ("ThreadName", () => { 
            stdout.printf ("Hello World");
            return 0;
    });

    thread.join ();
    return 0;
}


==2697== Invalid read of size 4
==2697==    at 0x50F2350: g_thread_unref (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
==2697==    by 0x400A65: _vala_main (in /home/lockner/test)
==2697==    by 0x400A9C: main (in /home/lockner/test)
==2697==  Address 0x5dc17e8 is 24 bytes inside a block of size 72 free'd
==2697==    at 0x4C2B60C: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2697==    by 0x50F2547: g_thread_join (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
==2697==    by 0x400A4B: _vala_main (in /home/lockner/test)
==2697==    by 0x400A9C: main (in /home/lockner/test)

When I manually add "thread = NULL;" between the join call and the _g_thread_unref0 macro in the generated C code, the invalid read is gone in the valgrind output.

g_thread_join (thread);
result = 0;
thread = NULL;
_g_thread_unref0 (thread);
return result;
2

There are 2 answers

0
lockner On BEST ANSWER

It turns out it was a missing annotation in glib-2.0.vapi

Adding [DestroysInstance] above join() solves the problem.

2
drahnr On

The issue is that g_thread_join already removes 1 reference. So the generated code does a double-free.

If you needed to add [DestroysInstance] this is clearly a bug in valac/the GThread binding.