> Am 17.06.2016 um 21:23 schrieb Gabriel Scherer : > > > 3. The finalizer is never called for blocks that are still alive; stated otherwise, a block that has been finalized can never been presented as a value to a C-stub anymore. > > I think that this does not hold in general: the finalizer should only be called when there is no reference to the value around, *but* the finalizer action can create a new reference (for example you may insert the value into a (live) global cache), so the value may be live after the finalizer has been called -- and be sent to a C stub, etc. It is definitely true that finalizers that are registered with Gc.finalise may generate new values (or make the value live again). But I do not see how to create a new value within a finalizer that is attached to a custom block on the C-layer. As the manual states, one must neither trigger a garbage collection in such a finalizer, nor call-back into OCaml code. > > This remark may not apply to your actual reproduction case (your finalizer shouldn't make the value reachable from the OCaml heap). > > (There were changes between the 4.03 development cycle that would explain the difference in behavior between beta1 and beta2, see in particular http://caml.inria.fr/mantis/view.php?id=7210 and https://github.com/ocaml/ocaml/pull/22 ; but I'll leave memory-runtime experts comment on that.) > > On Fri, Jun 17, 2016 at 2:09 PM, "Martin R. Neuhäußer" wrote: > Dear all, > > after an intense week of debugging some large C-bindings, I presume to have found a bug in OCaml’s garbage collection code or in its Weak module. > To summarize, it seems as if OCaml’s garbage collector and its Weak module sometimes release a custom block (by calling its finalizer) too early, i.e. when it is still reachable. > > I hesitate a bit before opening an „official“ issue on Mantis as I might very well overlook some detail. Therefore I’d like to double-check some of the assumptions that I have made when writing my C-stubs. Any corrections are highly welcome: > 1. Custom blocks may be moved around in memory by the GC, but they are never duplicated. > 2. The finalizer for each custom block that is allocated by caml_alloc_custom is called at most once. > 3. The finalizer is never called for blocks that are still alive; stated otherwise, a block that has been finalized can never been presented as a value to a C-stub anymore. > > There is a small example program available on github: https://github.com/martin-neuhaeusser/ocaml_bug where the above assumptions seem to be violated. > > The idea is as follows: > Each custom block that the example allocates contains a pointer to structure that is malloc’ed outside the OCaml heap; each custom block uniquely refers to such a structure. > Upon creation of a custom block, a special flag-value is stored in its corresponding (newly created) structure to indicate that the block is alive. Once a custom block’s finalizer is called, the flag is changed to indicate finalization of the block. I assume that after the finalizer returns, the custom block is unreachable (and perhaps its memory reclaimed by the GC); however, for debugging, I intentionally keep the custom block’s structure allocated on the unmanaged heap. Whenever a custom block is presented to the C-stubs, they check that the corresponding flag-value within its corresponding non-managed heap structure indicates liveness of the block. As it turns out, this invariant is violated, if the Weak module and the GC are stressed. > > Of course, it might very well be that there is a bug in my C-stubs that is responsible for that behavior. I tested with different versions of OCaml, with different outcomes: The example program terminates correctly with OCaml 3.12.1, 4.00.0, 4.00.1, 4.01.0, and 4.03.0+beta1 whereas it crashes due to the above error when compiled with OCaml 4.02.0, 4.02.1, 4.02.2, 4.02.3, 4.03.0+beta2, and the released 4.03.0. The tests were run on 64bit Debian Linux and 64bit MacOS X. > > I'd very much appreciate any help, hints to bugs in my code, or requests for clarification. > > Thanks and best regards, > Martin > > -- > Caml-list mailing list. Subscription management and archives: > https://sympa.inria.fr/sympa/arc/caml-list > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs >