mvz / gir_ffi

Auto-generate bindings for GObject based libraries at run time using FFI

Home Page:https://github.com/mvz/gir_ffi/wiki

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Finalizing a GBoxed should call g_boxed_free

jcupitt opened this issue · comments

When a GBoxed is finalized, gir_ffi should call g_boxed_free():

https://developer.gnome.org/gobject/unstable/gobject-Boxed-Types.html#g-boxed-free

It doesn't seem to at the moment:

$ cd GIT/gir_ffi
$ find . -name "*.rb" -exec grep -il boxed_free {} \;
$ 

If #52 is patched, perhaps with that terrible fix I submitted, this issue seems to be the final leak for my image processing library.

I've tried a naive implementation of this, but it leads to corruption of malloc's data.

Can you provide any concrete examples? This will allow me to start implementing this slowly.

I've been using this test:

https://github.com/jcupitt/gir_ffi-vips/blob/master/examples/test_leak6.rb

vips_array_double_new() is defined here:

https://github.com/jcupitt/libvips/blob/master/libvips/iofuncs/type.c#L843

The steps to reproduce would be something like:

git clone https://github.com/jcupitt/libvips.git
cd libvips
./bootstrap.sh
./configure --prefix=/some/private/prefix
make
make install

put /some/private/prefix/lib/girepository-1.0 on GI_TYPELIB_PATH, and I guess /some/private/prefix/lib on LD_LIBRARY_PATH, then:

git clone https://github.com/jcupitt/gir_ffi-vips.git
bundle
rake install
./examples/test_leak6.rb

That's a lot of code :( I can try to make a smaller test-case if you like.

I forgot, I have a test boxed type in vips, VipsThing:

https://github.com/jcupitt/libvips/blob/master/libvips/iofuncs/type.c#L90

So once vips is installed, you can test with:

$ irb
irb(main):001:0> require 'gir_ffi'
=> true
irb(main):003:0* GirFFI.setup :Vips
=> Vips
irb(main):007:0* a = Vips::Thing.new 12
vips_thing_new: 12 0x2eac3e0
=> #<Vips::Thing:0x0000000242e238 @struct=#<Vips::Thing::Struct:0x0000000242e210>>
irb(main):008:0> a = nil
=> nil
irb(main):009:0> GC.start
=> nil
irb(main):010:0> 

And you can see vips_thing_free() is not being called.

Thanks, I'm building a custom version of the vips debian package now that includes the GIR data.

The general problem GirFFI currently has is that it avoids the problem of figuring out what memory to free by not freeing any memory at all (reference counting is a different matter).

Simply calling g_boxed_free for any boxed type won't work, since sometimes ownership may have past to C land, or vice versa, we have simply borrowed it from C land and are not responsible for freeing it. The GIR data should provide enough information for GirFFI to do the right thing, so implementing this the right way is definitely possible.

Ah OK, you need to look for transfer annotations, I agree. It should be possible, for example the libvips python binding uses python-gi and runs the whole test suite with no leaks.

Thank you again for fixing this, it would be great to get ruby-vips updated to use gir_ffi.

Yeah, it's definitely possible, I just haven't gotten around to it.

@jcupitt I've finally managed to get an implementation that doesn't dump core. This means it's very conservative in what it frees. The changes are in current master.

I'm currently overhauling the pointer conversion system to be more explicit about what is going on in the generated methods. This will allow freeing the data in more cases.

The conservative freeing fix is part of GirFFI 0.9.5.

Hi @mvz, thanks! I've released my gem using gobject-introspection:

https://rubygems.org/gems/ruby-vips8/versions/0.1.0

But I've had several requests for a binding based on ffi instead, since gobject-introspection pulls in a lot of C. I'll have a go at moving ruby-vips8 on top of gir_ffi, it shouldn't be too much work.

@jcupitt Finalization is much improved in GirFFI version 0.10.1. I've tried your irb example, and although forcing garbage collection has become a little hard in Ruby 2.3, the vips_thing_free messages are being printed when I quit irb (well actually, pry).

I'll try and get back to gir_ffi, I've been sidetracked :( Thank you again for fixing this issue.