Project

General

Profile

Actions

Bug #18126

closed

Process termination three seconds after thread termination dumps core

Added by mame (Yusuke Endoh) 5 months ago. Updated 5 months ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:105048]

Description

The following code occasionally dumps core.

3000.times{Thread.new{}}
sleep 2.99
$ ruby test.rb
[BUG] Segmentation fault at 0x0000000000000440
ruby 3.0.1p64 (2021-04-05 revision 0fb782ee38) [x86_64-linux]

$

An internal batch script in our company aborts randomly due to this issue.

ko1 (Koichi Sasada) and I investigated the issue. When a Ruby Thread terminates, its internal pthread is reused by another Ruby Thread if a new Ruby Thread is created within three minutes. If it is not reused, the pthread frees sigaltstack memory (by using xfree) and terminates. However, if the Ruby process starts terminating while the pthread is waiting for three minutes, Ruby VM and GC is destructed. After that, xfree is no longer available, which leads to the segfault.

A simple solution is to use malloc/free instead of Ruby's xmalloc/xfree, but it would be better to trigger GC when memory allocation fails.

diff --git a/signal.c b/signal.c
index 764031e78a..f0ed7f90d4 100644
--- a/signal.c
+++ b/signal.c
@@ -560,7 +560,9 @@ rb_allocate_sigaltstack(void)
     if (!rb_sigaltstack_size_value) {
        rb_sigaltstack_size_value = rb_sigaltstack_size();
     }
-    return xmalloc(rb_sigaltstack_size_value);
+    void *altstack = malloc(rb_sigaltstack_size_value);
+    if (!altstack) rb_memerror();
+    return altstack;
 }

 /* alternate stack for SIGSEGV */
diff --git a/vm_core.h b/vm_core.h
index 5db3080b43..2962356212 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -136,7 +136,7 @@
 void *rb_allocate_sigaltstack(void);
 void *rb_register_sigaltstack(void *);
 #  define RB_ALTSTACK_INIT(var, altstack) var = rb_register_sigaltstack(altstack)
-#  define RB_ALTSTACK_FREE(var) xfree(var)
+#  define RB_ALTSTACK_FREE(var) free(var)
 #  define RB_ALTSTACK(var)  var
 #else /* noop */
 #  define RB_ALTSTACK_INIT(var, altstack)
Actions

Also available in: Atom PDF