summaryrefslogtreecommitdiff
path: root/vm.c
diff options
context:
space:
mode:
authorSamuel Williams <samuel.williams@oriontransfer.co.nz>2019-06-20 11:31:22 +1200
committerSamuel Williams <samuel.williams@oriontransfer.co.nz>2019-06-20 16:44:50 +1200
commite4cafa393f8fd4aa207f20b1d122884b4de99cf1 (patch)
tree78e6a286bcb55b6dd180153b1be9508090c25090 /vm.c
parentc26c51449461e3c8ee9bb4e1800933fb3d3caf67 (diff)
Ensure that vm_stack is cleared in `thread_cleanup_func_before_exec`.
If `vm_stack` is left dangling in a forked process, the gc attempts to scan it, but it is invalid and will cause a segfault. Therefore, we clear it before forking. In order to simplify this, `rb_ec_clear_vm_stack` was introduced.
Diffstat (limited to 'vm.c')
-rw-r--r--vm.c34
1 files changed, 25 insertions, 9 deletions
diff --git a/vm.c b/vm.c
index 258c1b5942..7ad6bdd264 100644
--- a/vm.c
+++ b/vm.c
@@ -2685,20 +2685,36 @@ thread_alloc(VALUE klass)
return obj;
}
+inline void
+rb_ec_set_vm_stack(rb_execution_context_t *ec, VALUE *stack, size_t size)
+{
+ ec->vm_stack = stack;
+ ec->vm_stack_size = size;
+}
+
void
rb_ec_initialize_vm_stack(rb_execution_context_t *ec, VALUE *stack, size_t size)
{
- rb_ec_set_vm_stack(ec, stack, size);
+ rb_ec_set_vm_stack(ec, stack, size);
+
+ ec->cfp = (void *)(ec->vm_stack + ec->vm_stack_size);
- ec->cfp = (void *)(ec->vm_stack + ec->vm_stack_size);
+ rb_vm_push_frame(ec,
+ NULL /* dummy iseq */,
+ VM_FRAME_MAGIC_DUMMY | VM_ENV_FLAG_LOCAL | VM_FRAME_FLAG_FINISH | VM_FRAME_FLAG_CFRAME /* dummy frame */,
+ Qnil /* dummy self */, VM_BLOCK_HANDLER_NONE /* dummy block ptr */,
+ 0 /* dummy cref/me */,
+ 0 /* dummy pc */, ec->vm_stack, 0, 0
+ );
+}
+
+void
+rb_ec_clear_vm_stack(rb_execution_context_t *ec)
+{
+ rb_ec_set_vm_stack(ec, NULL, 0);
- rb_vm_push_frame(ec,
- NULL /* dummy iseq */,
- VM_FRAME_MAGIC_DUMMY | VM_ENV_FLAG_LOCAL | VM_FRAME_FLAG_FINISH | VM_FRAME_FLAG_CFRAME /* dummy frame */,
- Qnil /* dummy self */, VM_BLOCK_HANDLER_NONE /* dummy block ptr */,
- 0 /* dummy cref/me */,
- 0 /* dummy pc */, ec->vm_stack, 0, 0
- );
+ // Avoid dangling pointers:
+ // ec->cfp = NULL;
}
static void