Hola, > Finalizers are set on pointer objects, so they’re invoked when the > pointer object goes out of scope. But: > > (eq? (make-pointer 123) (make-pointer 123)) > => #f I agree, but somehow this works: --8<---------------cut here---------------start------------->8--- scheme@(guile-user)> ,use (parted) scheme@(guile-user)> (eq? (get-device "/tmp/test.img") (get-device "/tmp/test.img")) $3 = #t --8<---------------cut here---------------end--------------->8--- denoting that the "pointer->device!" procedure is working correctly and the underlying pointer object returned by pointer->procedure is the same. > So a possible mistake is to add one finalizer on each pointer object and > have several pointer objects aliasing the same C object; that’s how you > can get the same “free” function called several times on the same C > object. I don't think that what's happening. I have monitored closely the %devices weak hash table and it never exceeds the total device count. We have multiple finalizers registered for the same C pointer but that's because the weak hash table may be cleaned by (gc) calls, leaving the opportunity for multiple finalizers registration on the same C pointer. I attached a reproducer that exposes the double free issue. --8<---------------cut here---------------start------------->8--- sudo -E guile ~/tmp/parted-bug.scm double free or corruption (!prev) Aborted --8<---------------cut here---------------end--------------->8--- We could save up somewhere which pointers have registered finalizers but that would prevent the devices garbage collection, in the same way as if %device was a plain hash table and not a weak one. That could well be a solution, as I cannot see at the moment how we could preserve this mechanism and avoid multiple finalization. Thanks, Mathieu