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

Bug#524908: libcairo-ocaml-dev: memory leak in Cairo_bigarray

Stéphane Glondu wrote:
> I can see that cairo_surface_t finalizer is always called when expected.
> ml_cairo_image_surface_create_for_data does register a global root, but
> caml_{register/remove}_global_root calls are always paired.

  The bug scenario in fact involves two custom blocks - cairo_surface_t and bigarray.
The cairo_surface_t finalizer (ml_final_cairo_surface_t) is called correctly, but the bigarray finalizer (caml_ba_finalize) is not called at all. The bigarray value somehow disappears from the OCaml heap. The corresponding bigarray data on the C heap is not reclaimed.

I've found a thread from caml-list archives which suggests that calling caml_{register/remove}_global_root from custom block finalizers might not be safe:


  I've tried to relate the bug to the OCaml GC. My current idea is as follows:

The custom block

- is always allocated in the major heap
- is reclaimed and finalizer is called in sweep_slice() in major_gc.c
- is also reclaimed in caml_compact_heap() in compact.c - and finalizer is not called!

    310           /* No pointers to the header and no infix header:
    311              the object was free. */
    312           *p = Make_header (Wosize_ehd (q), Tag_ehd (q), Caml_blue);
    313           p += Whsize_ehd (q);

The custom block is manipulated in this part of the GC code (confirmed by inserting a tag check here, and running bug.ml through the modified ocamlrun). Moreover, the bug does not appear if Gc.compact is replaced by Gc.full_major.

  Maybe someone who really understands OCaml GC code can confirm it?

Reply to: