-
Notifications
You must be signed in to change notification settings - Fork 5.4k
add VM Lock around rb_const_remove
operations (Module#remove_const)
#13717
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Without a VM Lock, there's an unlocked `rb_id_table_delete` for the class's const_tbl which can cause problems. Example: ```ruby class C CONSTANT = 3 end $VERBOSE = nil rs = [] 100.times do rs << Ractor.new do 10_000.times do if defined?(C::CONSTANT) C.send(:remove_const, :CONSTANT) rescue NameError else C.send(:const_set, :CONSTANT, 3) end end end end while rs.any? r, obj = Ractor.select(*rs) rs.delete(r) end ``` Without lock: ../ruby-release/test.rb:14: [BUG] Segmentation fault at 0x0000000000000001 -- Control frame information ----------------------------------------------- miniruby(82790,0x16f49f000) malloc: *** error for object 0x600000f880a0: pointer being freed was not allocated miniruby(82790,0x16f49f000) malloc: *** set a breakpoint in malloc_error_break to debug
Seems like we might be missing locking for const lookup as well. class C
CONSTANT = 3
end
$VERBOSE = nil
rs = []
100.times do
rs << Ractor.new do
10_000.times do
if defined?(C::CONSTANT)
C.send(:remove_const, :CONSTANT) rescue NameError
else
C.send(:const_set, :CONSTANT, 3)
end
C.const_get(:CONSTANT) rescue NameError
C.const_get(:CONSTANT) rescue NameError
end
end
end
while rs.any?
r, obj = Ractor.select(*rs)
rs.delete(r)
end
|
Should |
Yeah it's a good point, but for whatever reason this has always been allowed in ractors, and it was by design not by accident. As for why, I don't know but maybe it's to do with supporting autoloading in ractors. If you support autoloading constants, it's a small step away from supporting setting constants directly. |
@@ -44,7 +44,7 @@ void rb_free_const_table(struct rb_id_table *tbl); | |||
VALUE rb_const_source_location(VALUE, ID); | |||
|
|||
int rb_autoloading_value(VALUE mod, ID id, VALUE *value, rb_const_flag_t *flag); | |||
rb_const_entry_t *rb_const_lookup(VALUE klass, ID id); | |||
rb_const_entry_t *rb_const_lookup(VALUE klass, ID id, rb_const_entry_t *entry_out); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we make this return an int bool like st_lookup
?
|
Without a VM Lock, there's an unlocked
rb_id_table_delete
for the class's const_tbl which can cause problems. Example:Without lock:
../ruby-release/test.rb:14: [BUG] Segmentation fault at 0x0000000000000001 -- Control frame information ----------------------------------------------- miniruby(82790,0x16f49f000) malloc: *** error for object 0x600000f880a0: pointer being freed was not allocated miniruby(82790,0x16f49f000) malloc: *** set a breakpoint in malloc_error_break to debug