Ensure ruby_xfree won't segfault if called after vm_destruct

[Bug #19580]

The real-world scenario motivating this change is libxml2's pthread
code which uses `pthread_key_create` to set up a destructor that is
called at thread exit to free thread-local storage.

There is a small window of time -- after ruby_vm_destruct but before
the process exits -- in which a pthread may exit and the destructor is
called, leading to a segfault.

Please note that this window of time may be relatively large if
`atexit` is being used.
This commit is contained in:
Mike Dalessio 2023-04-04 23:55:43 -04:00 committed by Peter Zhu
parent 533423ebe4
commit 52e571fa72
Notes: git 2023-04-05 16:57:52 +00:00

12
gc.c
View File

@ -12581,8 +12581,16 @@ ruby_xrealloc2_body(void *ptr, size_t n, size_t size)
void
ruby_sized_xfree(void *x, size_t size)
{
if (x) {
objspace_xfree(&rb_objspace, x, size);
if (LIKELY(x)) {
/* It's possible for a C extension's pthread destructor function set by pthread_key_create
* to be called after ruby_vm_destruct and attempt to free memory. Fall back to mimfree in
* that case. */
if (LIKELY(GET_VM())) {
objspace_xfree(&rb_objspace, x, size);
}
else {
ruby_mimfree(x);
}
}
}