diff options
| author | Mike Dalessio <mike.dalessio@gmail.com> | 2023-04-04 23:55:43 -0400 |
|---|---|---|
| committer | Peter Zhu <peter@peterzhu.ca> | 2023-04-05 12:57:32 -0400 |
| commit | 52e571fa72debcd764765775bd1b76ee87e36d2d (patch) | |
| tree | 58e5de4f4a64709c50472e7070a0db67de795d20 | |
| parent | 533423ebe46ebfe3005198c12aa0d2c899c695ea (diff) | |
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.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/7663
| -rw-r--r-- | gc.c | 12 |
1 files changed, 10 insertions, 2 deletions
@@ -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); + } } } |
