summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--bootstraptest/test_objectspace.rb6
-rw-r--r--thread.c5
-rw-r--r--vm_core.h1
4 files changed, 23 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index f8ef5ae07b..62b58744f7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Sun Jul 10 16:41:32 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
+
+ * vm_core.h (typedef struct rb_vm_struct): create a new
+ 'inhibit_thread_createion' field.
+ * thread.c (rb_thread_terminate_all): set inhibit_thread_creation.
+ * thread.c (thread_s_new): don't permit to create new thread
+ if the VM is under destruction. Otherwise evil finalizer code
+ can make SEGV. [Bug #4992][ruby-core:37858]
+
+ * bootstraptest/test_objectspace.rb: new test for this fix.
+
Sun Jul 10 16:06:16 2011 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
* signal.c (sigsegv): use abort() instead of exit() when nested
diff --git a/bootstraptest/test_objectspace.rb b/bootstraptest/test_objectspace.rb
index a84b5b6f55..862a94e376 100644
--- a/bootstraptest/test_objectspace.rb
+++ b/bootstraptest/test_objectspace.rb
@@ -38,3 +38,9 @@ assert_normal_exit %q{
Mutex.new.lock
end
}, '[ruby-dev:44049]'
+
+assert_normal_exit %q{
+ ObjectSpace.define_finalizer("") do
+ Thread.new {}
+ end
+}, '[ruby-core:37858]'
diff --git a/thread.c b/thread.c
index cd5b49b868..ac72d5d038 100644
--- a/thread.c
+++ b/thread.c
@@ -367,6 +367,7 @@ rb_thread_terminate_all(void)
thread_debug("rb_thread_terminate_all (main thread: %p)\n", (void *)th);
st_foreach(vm->living_threads, terminate_i, (st_data_t)th);
+ vm->inhibit_thread_creation = 1;
while (!rb_thread_alone()) {
PUSH_TAG();
@@ -583,6 +584,10 @@ thread_s_new(int argc, VALUE *argv, VALUE klass)
{
rb_thread_t *th;
VALUE thread = rb_thread_alloc(klass);
+
+ if (GET_VM()->inhibit_thread_creation)
+ rb_raise(rb_eThreadError, "can't alloc thread");
+
rb_obj_call_init(thread, argc, argv);
GetThreadPtr(thread, th);
if (!th->first_args) {
diff --git a/vm_core.h b/vm_core.h
index cc450c5790..da912b5b60 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -285,6 +285,7 @@ typedef struct rb_vm_struct {
VALUE thgroup_default;
int running;
+ int inhibit_thread_creation;
int thread_abort_on_exception;
unsigned long trace_flag;
volatile int sleeper;