segfault on windows at dll-unload time when using custom memory functions
Background is at https://github.com/sparklemotion/nokogiri/issues/2241
Context
The Nokogiri rubygem configures libxml2 to use the Ruby interpreter's memory allocation functions, so that Ruby has an opportunity to run GC when libxml2 needs to allocate memory.
Previously, the changes introduced by !66 (closed) and !72 (closed) led to a segfault that is explained at https://github.com/sparklemotion/nokogiri/issues/2059 and fixed by Nick at 956534e0.
The problem
Unfortunately, what I missed at the time (because I wasn't testing on Windows against libxml2 master), is that the original commit from !66 (diffs) has the same issue: if a custom memory function is being used, the atexit
-registered call to xmlCleanupParser
can cause a segfault on Windows when DLLs are in use and libxml2 is configured to use custom memory functions.
Workaround
I've worked around this issue in Nokogiri by cutting a release that doesn't configure libxml2 to use Ruby's memory functions on Windows when libxml2 is loaded from a DLL.
See https://github.com/sparklemotion/nokogiri/pull/2240/files
Potential fix
I think the best way to address this might be to avoid calling xmlCleanupParser
at exit when custom memory functions are loaded.
I think it's OK to do this:
#if defined(WIN32) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
+ if (xmlFree == free)
atexit(xmlCleanupParser);
#endif
because the xmlmMemSetup
docs say "This has to be called before any other libxml routines !". Note that Nokogiri is well-behaved (mostly! ha ha) and calls xmlMemSetup
before calling xmlInitParser
.
I'll submit a PR momentarily with this suggested change.