crystal icon indicating copy to clipboard operation
crystal copied to clipboard

Fix: libxml manual memory management

Open ysbaddaden opened this issue 5 months ago • 0 comments
trafficstars

libxml allows to customize the memory allocators, which we used to plug the GC.

Under certain conditions (e.g. MT, libxml 2.14), this integration leads to segfaults when a GC cycle happens within a libxml function.

I'm not quite sure what's happening. Maybe libxml keeps pointers somewhere that the GC doesn't scan (thread locals?) and the GC collects it... though that would create random segfaults, not segfaults during GC. Anyway: removing the GC integration fixes the issue.

In addition, the libxml2 distributed in macOS 15.4 is patched to remove the custom memory allocators API :shrug:

Every other bindings to external libraries don't plug the GC but use manual memory management to free the external allocations when not needed anymore (automated through finalizers).

This PR removes the GC integration and uses explicit memory management through finalizers instead.

The XML::Node constructors now require a reference to the document's XML::Node because only the document must be freed, and nested nodes musn't be freed for as long as they are in the document's tree (but must be freed when removed from it). Because the constructors are public, this is a breaking change.

I don't think this is much of an issue when compared to having to deal with manual memory management if someone extended the libxml bindings.

I undocumented all the constructors that take an external libxml pointers. I think they should be internal API.

Depends on #15899. No more segfaults with libxml 2.14 (verified on linux). Closes #15619 (to be verified on macOS).

ysbaddaden avatar Jun 17 '25 09:06 ysbaddaden