[ruby-core:120884] [Ruby master Bug#21115] Etc.getgrgid is not Ractor-safe but is marked as such

Issue #21115 has been reported by Eregon (Benoit Daloze). ---------------------------------------- Bug #21115: Etc.getgrgid is not Ractor-safe but is marked as such https://bugs.ruby-lang.org/issues/21115 * Author: Eregon (Benoit Daloze) * Status: Open * ruby -v: ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [x86_64-linux] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- ```ruby require 'etc' 20.times.map do Ractor.new do 1000.times do raise unless Etc.getgrgid(Process.gid).gid == Process.gid end end end.each(&:take) ``` Running it a few times gives a segfault: ``` $ ruby ractor_getgrgid.rb ractor_getgrgid.rb:4: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues. #<Thread:0x00007f251b7d0478 run> terminated with exception (report_on_exception is true): ractor_getgrgid.rb:6:in 'block (3 levels) in <main>': unhandled exception from <internal:numeric>:257:in 'Integer#times' from ractor_getgrgid.rb:5:in 'block (2 levels) in <main>' #<Thread:0x00007f251b7dde70 run> terminated with exception (report_on_exception is true): ractor_getgrgid.rb:6:in 'block (3 levels) in <main>': unhandled exception from <internal:numeric>:257:in 'Integer#times' from ractor_getgrgid.rb:5:in 'block (2 levels) in <main>' ractor_getgrgid.rb:6: [BUG] Segmentation fault at 0x00000000706d7564 ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [x86_64-linux] -- Control frame information ----------------------------------------------- c:0005 p:---- s:0019 e:000018 CFUNC :getgrgid c:0004 p:0009 s:0014 e:000013 BLOCK ractor_getgrgid.rb:6 c:0003 p:0024 s:0011 e:000010 METHOD <internal:numeric>:257 c:0002 p:0005 s:0006 e:000005 BLOCK ractor_getgrgid.rb:5 [FINISH] c:0001 p:---- s:0003 e:000002 DUMMY [FINISH] ``` Etc is marked as Ractor-safe since https://github.com/ruby/ruby/pull/3954. But that is not correct, etc.c uses many C functions which are not thread-safe, such as `getgrgid()`. -- https://bugs.ruby-lang.org/

Issue #21115 has been updated by Eregon (Benoit Daloze). I think most methods of Etc have the same problem, so it's probably best to mark none of them as thread-safe, or only some known as thread-safe and frequently-used like `Etc.nprocessor` and `Etc.uname` (but should still be reviewed if they are indeed thread-safe). ---------------------------------------- Bug #21115: Etc.getgrgid is not Ractor-safe but is marked as such https://bugs.ruby-lang.org/issues/21115#change-111759 * Author: Eregon (Benoit Daloze) * Status: Open * ruby -v: ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [x86_64-linux] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- ```ruby require 'etc' 20.times.map do Ractor.new do 1000.times do raise unless Etc.getgrgid(Process.gid).gid == Process.gid end end end.each(&:take) ``` Running it a few times gives a segfault: ``` $ ruby ractor_getgrgid.rb ractor_getgrgid.rb:4: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues. #<Thread:0x00007f251b7d0478 run> terminated with exception (report_on_exception is true): ractor_getgrgid.rb:6:in 'block (3 levels) in <main>': unhandled exception from <internal:numeric>:257:in 'Integer#times' from ractor_getgrgid.rb:5:in 'block (2 levels) in <main>' #<Thread:0x00007f251b7dde70 run> terminated with exception (report_on_exception is true): ractor_getgrgid.rb:6:in 'block (3 levels) in <main>': unhandled exception from <internal:numeric>:257:in 'Integer#times' from ractor_getgrgid.rb:5:in 'block (2 levels) in <main>' ractor_getgrgid.rb:6: [BUG] Segmentation fault at 0x00000000706d7564 ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [x86_64-linux] -- Control frame information ----------------------------------------------- c:0005 p:---- s:0019 e:000018 CFUNC :getgrgid c:0004 p:0009 s:0014 e:000013 BLOCK ractor_getgrgid.rb:6 c:0003 p:0024 s:0011 e:000010 METHOD <internal:numeric>:257 c:0002 p:0005 s:0006 e:000005 BLOCK ractor_getgrgid.rb:5 [FINISH] c:0001 p:---- s:0003 e:000002 DUMMY [FINISH] ``` Etc is marked as Ractor-safe since https://github.com/ruby/ruby/pull/3954. But that is not correct, etc.c uses many C functions which are not thread-safe, such as `getgrgid()`. -- https://bugs.ruby-lang.org/

Issue #21115 has been updated by nobu (Nobuyoshi Nakada). MT-Safe variants such as `getgrgid_r` may be available, but we don't provide per-method ractor-safe declaration API, for now. Also `ractor_unsafe_check()` is not exposed. ---------------------------------------- Bug #21115: Etc.getgrgid is not Ractor-safe but is marked as such https://bugs.ruby-lang.org/issues/21115#change-111762 * Author: Eregon (Benoit Daloze) * Status: Open * ruby -v: ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [x86_64-linux] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- ```ruby require 'etc' 20.times.map do Ractor.new do 1000.times do raise unless Etc.getgrgid(Process.gid).gid == Process.gid end end end.each(&:take) ``` Running it a few times gives a segfault: ``` $ ruby ractor_getgrgid.rb ractor_getgrgid.rb:4: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues. #<Thread:0x00007f251b7d0478 run> terminated with exception (report_on_exception is true): ractor_getgrgid.rb:6:in 'block (3 levels) in <main>': unhandled exception from <internal:numeric>:257:in 'Integer#times' from ractor_getgrgid.rb:5:in 'block (2 levels) in <main>' #<Thread:0x00007f251b7dde70 run> terminated with exception (report_on_exception is true): ractor_getgrgid.rb:6:in 'block (3 levels) in <main>': unhandled exception from <internal:numeric>:257:in 'Integer#times' from ractor_getgrgid.rb:5:in 'block (2 levels) in <main>' ractor_getgrgid.rb:6: [BUG] Segmentation fault at 0x00000000706d7564 ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [x86_64-linux] -- Control frame information ----------------------------------------------- c:0005 p:---- s:0019 e:000018 CFUNC :getgrgid c:0004 p:0009 s:0014 e:000013 BLOCK ractor_getgrgid.rb:6 c:0003 p:0024 s:0011 e:000010 METHOD <internal:numeric>:257 c:0002 p:0005 s:0006 e:000005 BLOCK ractor_getgrgid.rb:5 [FINISH] c:0001 p:---- s:0003 e:000002 DUMMY [FINISH] ``` Etc is marked as Ractor-safe since https://github.com/ruby/ruby/pull/3954. But that is not correct, etc.c uses many C functions which are not thread-safe, such as `getgrgid()`. -- https://bugs.ruby-lang.org/

Issue #21115 has been updated by Eregon (Benoit Daloze). nobu (Nobuyoshi Nakada) wrote in #note-2:
MT-Safe variants such as `getgrgid_r` may be available, but we don't provide per-method ractor-safe declaration API, for now.
I think it's possible, like: ```c void Init_foo() { rb_ext_ractor_safe(true); #ifdef HAVE_GETGRGID_R rb_define_method(cls, "foo", ractor_safe_function, 0); #else rb_ext_ractor_safe(false); rb_define_method(cls, "foo", ractor_unsafe_function, 0); rb_ext_ractor_safe(true); // restore #endif } ``` But I am not sure it's worth the effort to use `getgrgid_r` and other `_r` methods (which are often difficult to use, e.g. to properly size the buffer). I think we should mark `Etc.getgrgid` and other Etc methods as always Ractor-unsafe. IOW, use `rb_ext_ractor_safe(true);`/`rb_ext_ractor_safe(false);` around actually Ractor-safe Etc methods, and let the rest be Ractor-unsafe. Alternatively Etc could lock explicitly around these thread-unsafe library calls. ---------------------------------------- Bug #21115: Etc.getgrgid is not Ractor-safe but is marked as such https://bugs.ruby-lang.org/issues/21115#change-111764 * Author: Eregon (Benoit Daloze) * Status: Open * ruby -v: ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [x86_64-linux] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- ```ruby require 'etc' 20.times.map do Ractor.new do 1000.times do raise unless Etc.getgrgid(Process.gid).gid == Process.gid end end end.each(&:take) ``` Running it a few times gives a segfault: ``` $ ruby ractor_getgrgid.rb ractor_getgrgid.rb:4: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues. #<Thread:0x00007f251b7d0478 run> terminated with exception (report_on_exception is true): ractor_getgrgid.rb:6:in 'block (3 levels) in <main>': unhandled exception from <internal:numeric>:257:in 'Integer#times' from ractor_getgrgid.rb:5:in 'block (2 levels) in <main>' #<Thread:0x00007f251b7dde70 run> terminated with exception (report_on_exception is true): ractor_getgrgid.rb:6:in 'block (3 levels) in <main>': unhandled exception from <internal:numeric>:257:in 'Integer#times' from ractor_getgrgid.rb:5:in 'block (2 levels) in <main>' ractor_getgrgid.rb:6: [BUG] Segmentation fault at 0x00000000706d7564 ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [x86_64-linux] -- Control frame information ----------------------------------------------- c:0005 p:---- s:0019 e:000018 CFUNC :getgrgid c:0004 p:0009 s:0014 e:000013 BLOCK ractor_getgrgid.rb:6 c:0003 p:0024 s:0011 e:000010 METHOD <internal:numeric>:257 c:0002 p:0005 s:0006 e:000005 BLOCK ractor_getgrgid.rb:5 [FINISH] c:0001 p:---- s:0003 e:000002 DUMMY [FINISH] ``` Etc is marked as Ractor-safe since https://github.com/ruby/ruby/pull/3954. But that is not correct, etc.c uses many C functions which are not thread-safe, such as `getgrgid()`. -- https://bugs.ruby-lang.org/

Issue #21115 has been updated by luke-gru (Luke Gruber). I think having a mutex per unsafe C extension to lock around those library calls would be a good idea. The alternative would be confusing to users imo, the ractor safety would be system dependant (OS version dependent and stdlib version dependent). ---------------------------------------- Bug #21115: Etc.getgrgid is not Ractor-safe but is marked as such https://bugs.ruby-lang.org/issues/21115#change-111787 * Author: Eregon (Benoit Daloze) * Status: Open * ruby -v: ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [x86_64-linux] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- ```ruby require 'etc' 20.times.map do Ractor.new do 1000.times do raise unless Etc.getgrgid(Process.gid).gid == Process.gid end end end.each(&:take) ``` Running it a few times gives a segfault: ``` $ ruby ractor_getgrgid.rb ractor_getgrgid.rb:4: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues. #<Thread:0x00007f251b7d0478 run> terminated with exception (report_on_exception is true): ractor_getgrgid.rb:6:in 'block (3 levels) in <main>': unhandled exception from <internal:numeric>:257:in 'Integer#times' from ractor_getgrgid.rb:5:in 'block (2 levels) in <main>' #<Thread:0x00007f251b7dde70 run> terminated with exception (report_on_exception is true): ractor_getgrgid.rb:6:in 'block (3 levels) in <main>': unhandled exception from <internal:numeric>:257:in 'Integer#times' from ractor_getgrgid.rb:5:in 'block (2 levels) in <main>' ractor_getgrgid.rb:6: [BUG] Segmentation fault at 0x00000000706d7564 ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [x86_64-linux] -- Control frame information ----------------------------------------------- c:0005 p:---- s:0019 e:000018 CFUNC :getgrgid c:0004 p:0009 s:0014 e:000013 BLOCK ractor_getgrgid.rb:6 c:0003 p:0024 s:0011 e:000010 METHOD <internal:numeric>:257 c:0002 p:0005 s:0006 e:000005 BLOCK ractor_getgrgid.rb:5 [FINISH] c:0001 p:---- s:0003 e:000002 DUMMY [FINISH] ``` Etc is marked as Ractor-safe since https://github.com/ruby/ruby/pull/3954. But that is not correct, etc.c uses many C functions which are not thread-safe, such as `getgrgid()`. -- https://bugs.ruby-lang.org/

Issue #21115 has been updated by Eregon (Benoit Daloze). I made a PR to mark Etc as not Ractor-safe for now: https://github.com/ruby/etc/pull/52 ---------------------------------------- Bug #21115: Etc.getgrgid is not Ractor-safe but is marked as such https://bugs.ruby-lang.org/issues/21115#change-112050 * Author: Eregon (Benoit Daloze) * Status: Open * ruby -v: ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [x86_64-linux] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- ```ruby require 'etc' 20.times.map do Ractor.new do 1000.times do raise unless Etc.getgrgid(Process.gid).gid == Process.gid end end end.each(&:take) ``` Running it a few times gives a segfault: ``` $ ruby ractor_getgrgid.rb ractor_getgrgid.rb:4: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues. #<Thread:0x00007f251b7d0478 run> terminated with exception (report_on_exception is true): ractor_getgrgid.rb:6:in 'block (3 levels) in <main>': unhandled exception from <internal:numeric>:257:in 'Integer#times' from ractor_getgrgid.rb:5:in 'block (2 levels) in <main>' #<Thread:0x00007f251b7dde70 run> terminated with exception (report_on_exception is true): ractor_getgrgid.rb:6:in 'block (3 levels) in <main>': unhandled exception from <internal:numeric>:257:in 'Integer#times' from ractor_getgrgid.rb:5:in 'block (2 levels) in <main>' ractor_getgrgid.rb:6: [BUG] Segmentation fault at 0x00000000706d7564 ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [x86_64-linux] -- Control frame information ----------------------------------------------- c:0005 p:---- s:0019 e:000018 CFUNC :getgrgid c:0004 p:0009 s:0014 e:000013 BLOCK ractor_getgrgid.rb:6 c:0003 p:0024 s:0011 e:000010 METHOD <internal:numeric>:257 c:0002 p:0005 s:0006 e:000005 BLOCK ractor_getgrgid.rb:5 [FINISH] c:0001 p:---- s:0003 e:000002 DUMMY [FINISH] ``` Etc is marked as Ractor-safe since https://github.com/ruby/ruby/pull/3954. But that is not correct, etc.c uses many C functions which are not thread-safe, such as `getgrgid()`. Also filed as https://github.com/ruby/etc/issues/50 -- https://bugs.ruby-lang.org/

Issue #21115 has been updated by Eregon (Benoit Daloze). Status changed from Open to Closed I merged https://github.com/ruby/etc/pull/52 which marks some methods as Ractor-safe and the rest as Ractor-unsafe so we can close this. ---------------------------------------- Bug #21115: Etc.getgrgid is not Ractor-safe but is marked as such https://bugs.ruby-lang.org/issues/21115#change-112424 * Author: Eregon (Benoit Daloze) * Status: Closed * ruby -v: ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [x86_64-linux] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- ```ruby require 'etc' 20.times.map do Ractor.new do 1000.times do raise unless Etc.getgrgid(Process.gid).gid == Process.gid end end end.each(&:take) ``` (inspired from https://github.com/ruby/spec/blob/658b578ce4b86cc06239a57ded62025d3fa00461/l...) Running it a few times gives a segfault: ``` $ ruby ractor_getgrgid.rb ractor_getgrgid.rb:4: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues. #<Thread:0x00007f251b7d0478 run> terminated with exception (report_on_exception is true): ractor_getgrgid.rb:6:in 'block (3 levels) in <main>': unhandled exception from <internal:numeric>:257:in 'Integer#times' from ractor_getgrgid.rb:5:in 'block (2 levels) in <main>' #<Thread:0x00007f251b7dde70 run> terminated with exception (report_on_exception is true): ractor_getgrgid.rb:6:in 'block (3 levels) in <main>': unhandled exception from <internal:numeric>:257:in 'Integer#times' from ractor_getgrgid.rb:5:in 'block (2 levels) in <main>' ractor_getgrgid.rb:6: [BUG] Segmentation fault at 0x00000000706d7564 ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [x86_64-linux] -- Control frame information ----------------------------------------------- c:0005 p:---- s:0019 e:000018 CFUNC :getgrgid c:0004 p:0009 s:0014 e:000013 BLOCK ractor_getgrgid.rb:6 c:0003 p:0024 s:0011 e:000010 METHOD <internal:numeric>:257 c:0002 p:0005 s:0006 e:000005 BLOCK ractor_getgrgid.rb:5 [FINISH] c:0001 p:---- s:0003 e:000002 DUMMY [FINISH] ``` Etc is marked as Ractor-safe since https://github.com/ruby/ruby/pull/3954. But that is not correct, etc.c uses many C functions which are not thread-safe, such as `getgrgid()`. Also filed as https://github.com/ruby/etc/issues/50 -- https://bugs.ruby-lang.org/
participants (3)
-
Eregon (Benoit Daloze)
-
luke-gru (Luke Gruber)
-
nobu (Nobuyoshi Nakada)