ml.ruby-lang.org
Sign In Sign Up
Manage this list Sign In Sign Up

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

ruby-core

Thread Start a new thread
Download
Threads by month
  • ----- 2026 -----
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2025 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
ruby-core@ml.ruby-lang.org

June 2025

  • 4 participants
  • 229 discussions
[ruby-core:121450] [Ruby Bug#21200] Ractor spuriously hangs, segfault or errors
by Eregon (Benoit Daloze) 09 Sep '26

09 Sep '26
Issue #21200 has been reported by Eregon (Benoit Daloze). ---------------------------------------- Bug #21200: Ractor spuriously hangs, segfault or errors https://bugs.ruby-lang.org/issues/21200 * Author: Eregon (Benoit Daloze) * Status: Open * Assignee: ractor * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- For a new test `test_ractor_parallel` I added in https://github.com/ruby/etc/pull/52/files This seems a Ractor bug. Example failures: https://github.com/ruby/ruby/actions/runs/14097239052/job/39486770259?pr=12… ``` 1) Failure: TestEtc#test_ractor_parallel [/Users/runner/work/ruby/ruby/src/test/etc/test_etc.rb:178]: assert_separately failed with error message pid 51588 exit 0 | [BUG] ``` https://github.com/ruby/ruby/actions/runs/14094646363/job/39479353266?pr=12… ``` TestEtc#test_ractor_parallel [/Users/runner/work/ruby/ruby/src/test/etc/test_etc.rb:178]: assert_separately failed with error message pid 47346 exit 0 | [BUG] pthread_mutex_lock: Invalid argument (EINVAL) | ruby 3.5.0dev (2025-03-26T22:25:25Z pull/12984/merge 1ea32181b7) +PRISM [arm64-darwin23] | | -- Crash Report log information -------------------------------------------- | See Crash Report log file in one of the following locations: | * ~/Library/Logs/DiagnosticReports | * /Library/Logs/DiagnosticReports | for more details. | Don't forget to include the above Crash Report log file in bug reports. | | -- Control frame information ----------------------------------------------- | | | -- Threading information --------------------------------------------------- | Total ractor count: 1 | Ruby thread count for this ractor: 0 | | -- C level backtrace information ------------------------------------------- | [BUG] Segmentation fault at 0xfffffffffffffff8 | ruby 3.5.0dev (2025-03-26T22:25:25Z pull/12984/merge 1ea32181b7) +PRISM [arm64-darwin23] | | -- Crash Report log information -------------------------------------------- | See Crash Report log file in one of the following locations: | * ~/Library/Logs/DiagnosticReports | * /Library/Logs/DiagnosticReports | for more details. | Don't forget to include the above Crash Report log file in bug reports. | | Crashed while printing bug report | [IMPORTANT] | Don't forget to include the Crash Report log file under | DiagnosticReports directory in bug reports. | ``` https://github.com/ruby/ruby/actions/runs/14069270994/job/39402894235#step:… ``` 1) Error: TestEtc#test_ractor_parallel: Test::Unit::ProxyError: execution of Test::Unit::CoreAssertions#assert_separately expired timeout (10 sec) pid 145797 killed by SIGKILL (signal 9) | /home/runner/work/ruby/ruby/src/test/etc/test_etc.rb:178:in 'TestEtc#test_ractor_parallel' ``` The test has been disabled for now in https://github.com/ruby/ruby/pull/12992. -- https://bugs.ruby-lang.org/
2 1
0 0
[ruby-core:111960] [Ruby master Bug#19364] Issue with tracepoint enable/disable across ractors
by luke-gru (Luke Gruber) 09 Sep '26

09 Sep '26
Issue #19364 has been reported by luke-gru (Luke Gruber). ---------------------------------------- Bug #19364: Issue with tracepoint enable/disable across ractors https://bugs.ruby-lang.org/issues/19364 * Author: luke-gru (Luke Gruber) * Status: Open * Priority: Normal * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- This sometimes segfaults: ```ruby def test_enable_disable_in_multiple_ractors_with_target rs = [] 100.times do |i| # setup new iseqs Kernel.define_method :"my_method_to_change_for_tracing_#{i}" do true end end 100.times do |i| rs << Ractor.new(i) do |j| meth = :"my_method_to_change_for_tracing_#{j}" tp = TracePoint.new(:line) { } # local to ractor 100.times do tp.enable(target: method(meth)) # change iseq internals of given method, should be done with lock tp.disable # disable hooks should hold lock too, changes method definition internals end end end rs.each(&:take) # shouldn't raise end test_enable_disable_in_multiple_ractors_with_target() ``` Changing iseq internals is done without the VM lock. This is true in Tracepoint#enable and Tracepoint#disable methods. I have a patch coming. -- https://bugs.ruby-lang.org/
3 2
0 0
[ruby-core:116061] [Ruby master Bug#20158] Ractor affects Coverage results
by janosch-x 09 Sep '26

09 Sep '26
Issue #20158 has been reported by janosch-x (Janosch Müller). ---------------------------------------- Bug #20158: Ractor affects Coverage results https://bugs.ruby-lang.org/issues/20158 * Author: janosch-x (Janosch Müller) * Status: Open * Priority: Normal * ruby -v: ruby 3.3.0preview1 (2023-05-12 master a1b01e7701) [arm64-darwin22] * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- I have a large rspec test suite. I found that if I call a Ractor, the Coverage results are strongly affected, i.e. almost all files appear to be uncovered. This happens even if I only ever call a Ractor before the library or rspec are required. Unfortunately, I was not able to build a simple repro yet. I assume it is a timing thing and only affects larger suites, or it only happens if there are multiple files, and maybe if the library lazily requires its sub-modules? However, I guess this should produce the same results when added to the spec_helper.rb of other large suites: ```ruby # Ractor.new { nil } # uncomment this to affect coverage results require 'coverage' Coverage.start # require library, set up rspec etc. RSpec.configuration.after(:suite) do # this number is greatly reduced and unstable when calling Ractor above p Coverage.result.values.sum { |arr| arr.sum(&:to_i) } end ``` I had this problem in [this library](https://github.com/jaynetics/character_set/). The problem affects simplecov users as well, as described [here](https://github.com/simplecov-ruby/simplecov/issues/1058). -- https://bugs.ruby-lang.org/
4 5
0 0
[ruby-core:121941] [Ruby Bug#21315] Finalizers violate the `rb_ractor_confirm_belonging` assertion
by byroot (Jean Boussier) 09 Sep '26

09 Sep '26
Issue #21315 has been reported by byroot (Jean Boussier). ---------------------------------------- Bug #21315: Finalizers violate the `rb_ractor_confirm_belonging` assertion https://bugs.ruby-lang.org/issues/21315 * Author: byroot (Jean Boussier) * Status: Open * Assignee: ractor * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- Reproduction (with assertions enabled): ```ruby require "tempfile" Ractor.new do 10.times do Tempfile.new end end.take GC.start ``` ``` <OBJ_INFO:rb_ractor_confirm_belonging@../src/ractor_core.h:375> (File) /home/runner/work/ruby/ruby/src/lib/tempfile.rb:387: [BUG] rb_ractor_confirm_belonging object-ractor id:1, current-ractor id:2 ruby 3.5.0dev (2025-05-09T15:51:24Z pull/13291/merge e289a1dc58) +PRISM [x86_64-linux] -- Control frame information ----------------------------------------------- c:0005 p:0007 s:0025 e:000024 METHOD /home/runner/work/ruby/ruby/src/lib/tempfile.rb:387 [FINISH] c:0004 p:0022 s:0020 e:000019 METHOD /home/runner/work/ruby/ruby/src/lib/prism/parse_result.rb:833 [FINISH] c:0003 p:---- s:0012 e:000011 CFUNC :parse_lex_file c:0002 p:0006 s:0007 e:000006 BLOCK /home/runner/work/ruby/ruby/src/test/prism/ractor_test.rb:26 [FINISH] c:0001 p:---- s:0003 e:000002 DUMMY [FINISH] -- Ruby level backtrace information ---------------------------------------- /home/runner/work/ruby/ruby/src/test/prism/ractor_test.rb:26:in 'block in test_parse_lex_file' /home/runner/work/ruby/ruby/src/test/prism/ractor_test.rb:26:in 'parse_lex_file' /home/runner/work/ruby/ruby/src/lib/prism/parse_result.rb:833:in 'initialize' /home/runner/work/ruby/ruby/src/lib/tempfile.rb:387:in 'call' -- Threading information --------------------------------------------------- Total ractor count: 2 Ruby thread count for this ractor: 1 -- C level backtrace information ------------------------------------------- /home/runner/work/ruby/ruby/build/ruby(rb_print_backtrace+0x14) [0x561441aeedbf] ../src/vm_dump.c:843 /home/runner/work/ruby/ruby/build/ruby(rb_vm_bugreport) ../src/vm_dump.c:1175 /home/runner/work/ruby/ruby/build/ruby(bug_report_end+0x0) [0x561441aa3f39] ../src/error.c:1097 /home/runner/work/ruby/ruby/build/ruby(rb_bug_without_die_internal) ../src/error.c:1097 /home/runner/work/ruby/ruby/build/ruby(die+0x0) [0x5614416e237f] ../src/error.c:1115 /home/runner/work/ruby/ruby/build/ruby(rb_bug) ../src/error.c:1117 /home/runner/work/ruby/ruby/build/ruby(rb_ractor_confirm_belonging+0xde) [0x56144188c6be] ../src/ractor_core.h:376 /home/runner/work/ruby/ruby/build/ruby(vm_exec_core+0xef) [0x5614418b23ef] /home/runner/work/ruby/ruby/build/vm.inc:2500 /home/runner/work/ruby/ruby/build/ruby(rb_vm_exec+0x156) [0x5614418a4676] ../src/vm.c:2618 /home/runner/work/ruby/ruby/build/ruby(vm_call0_cc+0x13d) [0x5614418aa1dd] ../src/vm_eval.c:101 /home/runner/work/ruby/ruby/build/ruby(rb_vm_call0+0x4c) [0x5614418b1cc5] ../src/vm_eval.c:61 /home/runner/work/ruby/ruby/build/ruby(rb_vm_call_kw) ../src/vm_eval.c:326 /home/runner/work/ruby/ruby/build/ruby(rb_check_funcall_default_kw) ../src/vm_eval.c:694 /home/runner/work/ruby/ruby/build/ruby(rb_gc_run_obj_finalizer+0x1cf) [0x56144170220f] ../src/gc.c:306 /home/runner/work/ruby/ruby/build/ruby(rb_multi_ractor_p+0x0) [0x56144170246f] ../src/gc/default/default.c:2820 /home/runner/work/ruby/ruby/build/ruby(rb_vm_lock_enter) ../src/vm_sync.h:74 /home/runner/work/ruby/ruby/build/ruby(rb_gc_vm_lock) ../src/gc.c:137 /home/runner/work/ruby/ruby/build/ruby(finalize_list) ../src/gc/default/default.c:2843 /home/runner/work/ruby/ruby/build/ruby(finalize_deferred_heap_pages) ../src/gc/default/default.c:2866 ``` I think it wouldn't be hard to disable that check when running a finalizer, but I don't know if it's the correct thing to do. -- https://bugs.ruby-lang.org/
5 8
0 0
[ruby-core:112091] [Ruby master Bug#19387] Issue with ObjectSpace.each_objects not returning IO objects after starting a ractor
by luke-gru (Luke Gruber) 09 Sep '26

09 Sep '26
Issue #19387 has been reported by luke-gru (Luke Gruber). ---------------------------------------- Bug #19387: Issue with ObjectSpace.each_objects not returning IO objects after starting a ractor https://bugs.ruby-lang.org/issues/19387 * Author: luke-gru (Luke Gruber) * Status: Open * Priority: Normal * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- ```ruby r = Ractor.new do receive # block, the problem is not the termination of the ractor but the starting end ObjectSpace.each_object(IO) { |io| p io # we get no objects } ``` -- https://bugs.ruby-lang.org/
6 9
0 0
[ruby-core:115328] [Ruby master Bug#19996] `RUBY_MN_THREADS=1` triggers Action Cable unit test failures
by yahonda (Yasuo Honda) 08 Sep '26

08 Sep '26
Issue #19996 has been reported by yahonda (Yasuo Honda). ---------------------------------------- Bug #19996: `RUBY_MN_THREADS=1` triggers Action Cable unit test failures https://bugs.ruby-lang.org/issues/19996 * Author: yahonda (Yasuo Honda) * Status: Open * Priority: Normal * ruby -v: ruby 3.3.0dev (2023-11-09T16:24:15Z :detached: c49adfab5d) +MN [x86_64-linux] * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- ### Steps to reproduce 1. Install `ruby 3.3.0dev` 2. Set `RUBY_MN_THREADS=1` environment variable 3. git clone https://github.com/rails/rails cd rails rm Gemfile.lock bundle install cd actioncable bin/test test/channel/base_test.rb test/subscription_adapter/redis_test.rb test/channel/test_case_test.rb test/subscription_adapter/redis_test.rb test/client_test.rb --seed 14800 ``` ### Expected behavior It should pass as not setting ``` $ unset RUBY_MN_THREADS $ bin/test test/channel/base_test.rb test/subscription_adapter/redis_test.rb test/channel/test_case_test.rb test/subscription_adapter/redis_test.rb test/client_test.rb --seed 14800 /home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/gems/minitest-5.20.0/lib/minitest.rb:3: warning: mutex_m which will no longer be part of the default gems since Ruby 3.4.0. Add mutex_m to your Gemfile or gemspec. Run options: --seed 14800 # Running: ......................................................................... Finished in 12.031310s, 6.0675 runs/s, 46.7115 assertions/s. 73 runs, 562 assertions, 0 failures, 0 errors, 0 skips $ ``` ### Actual behavior It usually fails as follows. ``` $ bin/test test/channel/base_test.rb test/subscription_adapter/redis_test.rb test/channel/test_case_test.rb test/subscription_adapter/redis_test.rb test/client_test.rb --seed 14800 /home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/gems/minitest-5.20.0/lib/minitest.rb:3: warning: mutex_m which will no longer be part of the default gems since Ruby 3.4.0. Add mutex_m to your Gemfile or gemspec. Run options: --seed 14800 # Running: ..................................................F Failure: RedisAdapterTest::AlternateConfiguration#test_channel_prefix [/home/yahonda/src/github.com/rails/rails/actioncable/test/subscription_adapter/common.rb:35]: Expected #<Concurrent::Event:0x00007f0b2698d4f0 @__Lock__=#<Thread::Mutex:0x00007f0b26f8cab8>, @__Condition__=#<Thread::ConditionVariable:0x00007f0b26f8ca90>, @set=false, @iteration=0> to be set?. bin/test test/subscription_adapter/channel_prefix.rb:6 .F Failure: RedisAdapterTest::AlternateConfiguration#test_multiple_broadcast [/home/yahonda/src/github.com/rails/rails/actioncable/test/subscription_adapter/common.rb:35]: Expected #<Concurrent::Event:0x00007f0b2698a4d0 @__Lock__=#<Thread::Mutex:0x00007f0b26fac688>, @__Condition__=#<Thread::ConditionVariable:0x00007f0b26fac4f8>, @set=false, @iteration=0> to be set?. bin/test test/subscription_adapter/common.rb:74 E Error: ClientTest#test_interacting_clients: ThreadError: queue empty <internal:thread_sync>:18:in `pop' /home/yahonda/src/github.com/rails/rails/actioncable/test/client_test.rb:168:in `read_message' /home/yahonda/src/github.com/rails/rails/actioncable/test/client_test.rb:241:in `block (2 levels) in test_interacting_clients' /home/yahonda/src/github.com/rails/rails/actioncable/test/client_test.rb:218:in `block (2 levels) in concurrently' /home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/promises.rb:1583:in `evaluate_to' /home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/promises.rb:1766:in `block in on_resolvable' /home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:352:in `run_task' /home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:343:in `block (3 levels) in create_worker' <internal:kernel>:187:in `loop' /home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:334:in `block (2 levels) in create_worker' /home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:333:in `catch' /home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:333:in `block in create_worker' /home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/promises.rb:1258:in `raise' /home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/promises.rb:1258:in `wait_until_resolved!' /home/yahonda/.rbenv/versions/trunk/lib/ruby/gems/3.3.0+0/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/promises.rb:988:in `value!' /home/yahonda/src/github.com/rails/rails/actioncable/test/client_test.rb:218:in `map' /home/yahonda/src/github.com/rails/rails/actioncable/test/client_test.rb:218:in `concurrently' /home/yahonda/src/github.com/rails/rails/actioncable/test/client_test.rb:240:in `block in test_interacting_clients' /home/yahonda/src/github.com/rails/rails/actioncable/test/client_test.rb:90:in `with_puma_server' /home/yahonda/src/github.com/rails/rails/actioncable/test/client_test.rb:234:in `test_interacting_clients' bin/test test/client_test.rb:233 E Error: ClientTest#test_disappearing_client: ThreadError: queue empty <internal:thread_sync>:18:in `pop' /home/yahonda/src/github.com/rails/rails/actioncable/test/client_test.rb:168:in `read_message' /home/yahonda/src/github.com/rails/rails/actioncable/test/client_test.rb:275:in `block in test_disappearing_client' /home/yahonda/src/github.com/rails/rails/actioncable/test/client_test.rb:90:in `with_puma_server' /home/yahonda/src/github.com/rails/rails/actioncable/test/client_test.rb:273:in `test_disappearing_client' bin/test test/client_test.rb:272 .................. Finished in 1323.812615s, 0.0551 runs/s, 0.3830 assertions/s. 73 runs, 507 assertions, 2 failures, 2 errors, 0 skips $ ``` -- https://bugs.ruby-lang.org/
3 2
0 0
[ruby-core:118182] [Ruby master Bug#20526] File.open(encoding: "bom|utf-8") converts "\r\n" to "\n" on Windows
by kou (Kouhei Sutou) 08 Sep '26

08 Sep '26
Issue #20526 has been reported by kou (Kouhei Sutou). ---------------------------------------- Bug #20526: File.open(encoding: "bom|utf-8") converts "\r\n" to "\n" on Windows https://bugs.ruby-lang.org/issues/20526 * Author: kou (Kouhei Sutou) * Status: Open * Target version: 3.2 * ruby -v: ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x64-mingw-ucrt] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- I'm not sure whether this is an intentional behavior but it seems that `encoding: "utf-8"` doesn't change newline conversion but `encoding: "bom|utf-8"` changes newline conversion: ```ruby File.write("a.txt", "a\r\n") File.read("a.txt").bytes # => [97, 13, 10] File.open("a.txt", encoding: "utf-8") {|f| f.read.bytes} # => [97, 10, 10] File.open("a.txt", encoding: "bom|utf-8") {|f| f.read.bytes} # => [97, 10] XXX: \r\n -> \n File.open("a.txt", encoding: "bom|utf-8", universal_newline: false) {|f| f.read.bytes} # => [97, 13, 10] ``` Note that the `XXX: ` line the above codes. Is this an intentional behavior? -- https://bugs.ruby-lang.org/
3 5
0 0
[ruby-core:120897] [Ruby master Bug#21119] Programs containing `Dir.glob` with a thread executing a CPU-heavy task run very slowly.
by genya0407 (Yusuke Sangenya) 05 Sep '26

05 Sep '26
Issue #21119 has been reported by genya0407 (Yusuke Sangenya). ---------------------------------------- Bug #21119: Programs containing `Dir.glob` with a thread executing a CPU-heavy task run very slowly. https://bugs.ruby-lang.org/issues/21119 * Author: genya0407 (Yusuke Sangenya) * Status: Open * ruby -v: ruby 3.5.0dev (2025-02-06T14:10:34Z master adbf9c5b36) +PRISM [arm64-darwin24] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- Executing the following code in Ruby 3.4.1 takes a very long time, especially when there are many files \(100~\) in the current directory. This delay does not occur in Ruby 3.3.6. ## Reproducible script ```ruby # hoge.rb # Launch a thread to execute CPU-heavy task Thread.new do loop do arr = [] 100.times do arr << rand(1...100) end end end # Execute a program containing `Dir.glob` in the main thread. 10.times do Dir.glob('*') puts "aaaa" end ``` ## Execution Results Executiong the above code in Ruby 3.4.1 takes **119.43s**. ```shell $ ruby -v ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [arm64-darwin24] $ time ruby hoge.rb aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa ruby hoge.rb 119.43s user 0.30s system 99% cpu 1:59.89 total ``` Executing it in Ruby master also takes **118.87s**. ```shell $ ~/opt-ruby/bin/ruby -v ruby 3.5.0dev (2025-02-06T14:10:34Z master adbf9c5b36) +PRISM [arm64-darwin24] $ time ~/opt-ruby/bin/ruby hoge.rb aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa ~/opt-ruby/bin/ruby hoge.rb 118.87s user 0.46s system 99% cpu 2:00.45 total ``` Executing it in Ruby 3.3.6 takes only **2.22s**. ```shell $ ruby -v ruby 3.3.6 (2024-11-05 revision 75015d4c1f) [arm64-darwin24] $ time ruby hoge.rb aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa aaaa ruby hoge.rb 2.22s user 0.03s system 98% cpu 2.286 total ``` So, there are roughly **50x** delays. ## Possible Cause From Ruby 3.4.0, `Dir.glob` releases the GVL frequently. * https://bugs.ruby-lang.org/issues/20587 * https://github.com/ruby/ruby/pull/11147 Due to this change, when a CPU-heavy thread releases the GVL, `Dir.glob` also releases the GVL immediately. As a result, `Dir.glob` gets significantly delayed because it has to continuously regain the GVL causing a major slowdown in execution. ## Note about Execution Results I measured the execution results under a stress condition, with 100 files in the current directory. If there are fewer files, the slowdown may be less pronounced. -- https://bugs.ruby-lang.org/
6 6
0 0
[ruby-core:116615] [Ruby master Bug#20243] M:N threading VM_ASSERT failure in rb_current_execution_context with clang 17 (on Linux)
by kjtsanaktsidis (KJ Tsanaktsidis) 30 Aug '26

30 Aug '26
Issue #20243 has been reported by kjtsanaktsidis (KJ Tsanaktsidis). ---------------------------------------- Bug #20243: M:N threading VM_ASSERT failure in rb_current_execution_context with clang 17 (on Linux) https://bugs.ruby-lang.org/issues/20243 * Author: kjtsanaktsidis (KJ Tsanaktsidis) * Status: Open * Priority: Normal * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- When building with Clang 17 and `-DVM_CHECK_MODE=1` (with the following configure) ``` optflags="-ggdb3 -fno-omit-frame-pointer -fno-optimize-sibling-calls -O3" cflags="-DVM_CHECK_MODE=1" CC=clang ../configure --prefix=/home/kj/ruby/installed --enable-yjit=dev --disable-install-doc ``` And then running the following script with the built `./miniruby` (which is actually from `bootstraptest/test_ractor.rb`): ```ruby counts = [] counts << Ractor.count ractors = (1..3).map { Ractor.new { Ractor.receive } } counts << Ractor.count ractors[0].send('End 0').take sleep 0.1 until ractors[0].inspect =~ /terminated/ counts << Ractor.count ractors[1].send('End 1').take sleep 0.1 until ractors[1].inspect =~ /terminated/ counts << Ractor.count ractors[2].send('End 2').take sleep 0.1 until ractors[2].inspect =~ /terminated/ counts << Ractor.count counts.inspect ``` I get the following crash: ``` Assertion Failed: ../vm_core.h:1957:rb_current_execution_context:ec == rb_current_ec_noinline() ruby 3.4.0dev (2024-02-07T07:52:06Z ktsanaktsidis/igno.. 5cc6d944c2) [x86_64-linux] -- Control frame information ----------------------------------------------- c:0003 p:0003 s:0010 e:000009 METHOD <internal:ractor>:431 c:0002 p:0004 s:0006 e:000005 BLOCK ractor_crash.rb:3 [FINISH] c:0001 p:---- s:0003 e:000002 DUMMY [FINISH] -- Ruby level backtrace information ---------------------------------------- ractor_crash.rb:3:in `block (2 levels) in <main>' <internal:ractor>:431:in `receive' -- Threading information --------------------------------------------------- Total ractor count: 2 Ruby thread count for this ractor: 1 -- C level backtrace information ------------------------------------------- /home/kj/ruby/build/miniruby(rb_print_backtrace+0x14) [0x55faa97a4ebd] ../vm_dump.c:820 /home/kj/ruby/build/miniruby(rb_vm_bugreport) ../vm_dump.c:1151 /home/kj/ruby/build/miniruby(rb_assert_failure+0x81) [0x55faa94d2719] ../error.c:1131 ./miniruby(thread_sched_wait_running_turn+0x2e9) [0x55faa9726f59] /home/kj/ruby/build/miniruby(rb_ractor_sched_sleep+0x10b) [0x55faa972687b] ../thread_pthread.c:1348 /home/kj/ruby/build/miniruby(ractor_check_ints+0x0) [0x55faa968b328] ../ractor.c:683 /home/kj/ruby/build/miniruby(ractor_sleep_with_cleanup) ../ractor.c:684 /home/kj/ruby/build/miniruby(ractor_sleep+0x15) [0x55faa968adf4] ../ractor.c:701 /home/kj/ruby/build/miniruby(ractor_wait_receive) ../ractor.c:748 /home/kj/ruby/build/miniruby(ractor_receive+0x1f) [0x55faa968768e] ../ractor.c:762 /home/kj/ruby/build/miniruby(builtin_inline_class_431) ../ractor.rb:432 /home/kj/ruby/build/miniruby(builtin_invoker0+0x6) [0x55faa978fc66] ../vm_insnhelper.c:6746 /home/kj/ruby/build/miniruby(invoke_bf+0x39) [0x55faa979816e] ../vm_insnhelper.c:6886 /home/kj/ruby/build/miniruby(vm_invoke_builtin_delegate) ../vm_insnhelper.c:6909 /home/kj/ruby/build/miniruby(rb_vm_check_ints+0x0) [0x55faa9771fac] ../insns.def:1533 /home/kj/ruby/build/miniruby(vm_pop_frame) ../vm_insnhelper.c:419 /home/kj/ruby/build/miniruby(vm_exec_core) ../insns.def:1537 /home/kj/ruby/build/miniruby(vm_exec_loop+0x0) [0x55faa9767f02] ../vm.c:2489 /home/kj/ruby/build/miniruby(rb_vm_exec) ../vm.c:2492 /home/kj/ruby/build/miniruby(invoke_block+0x6f) [0x55faa9781a58] ../vm.c:1512 /home/kj/ruby/build/miniruby(invoke_iseq_block_from_c) ../vm.c:1582 /home/kj/ruby/build/miniruby(invoke_block_from_c_proc) ../vm.c:1680 /home/kj/ruby/build/miniruby(vm_invoke_proc) ../vm.c:1710 /home/kj/ruby/build/miniruby(rb_vm_invoke_proc_with_self+0x5a) [0x55faa9781eaa] ../vm.c:1745 /home/kj/ruby/build/miniruby(thread_do_start_proc+0x199) [0x55faa9739e19] ../thread.c:574 /home/kj/ruby/build/miniruby(thread_do_start+0x6c) [0x55faa973933f] ../thread.c:618 /home/kj/ruby/build/miniruby(thread_start_func_2) ../thread.c:668 /home/kj/ruby/build/miniruby(rb_native_mutex_lock+0x0) [0x55faa973a141] ../thread_pthread.c:2234 /home/kj/ruby/build/miniruby(thread_sched_lock_) ../thread_pthread.c:387 /home/kj/ruby/build/miniruby(call_thread_start_func_2) ../thread_pthread_mn.c:436 /home/kj/ruby/build/miniruby(co_start) ../thread_pthread_mn.c:434 ``` The failing assertion is this one in vm_core.h: https://github.com/ruby/ruby/blob/42c36269403baac67b0d5dc1d6d6e31168cf6a1f/…. It actually has a very helpful comment. ``` /* On the shared objects, `__tls_get_addr()` is used to access the TLS * and the address of the `ruby_current_ec` can be stored on a function * frame. However, this address can be mis-used after native thread * migration of a coroutine. * 1) Get `ptr =&ruby_current_ec` op NT1 and store it on the frame. * 2) Context switch and resume it on the NT2. * 3) `ptr` is used on NT2 but it accesses to the TLS on NT1. * This assertion checks such misusage. * * To avoid accidents, `GET_EC()` should be called once on the frame. * Note that inlining can produce the problem. */ VM_ASSERT(ec == rb_current_ec_noinline()); ``` What seems to be happening is exactly that. This is a disassembly of the relevant bits of `thread_sched_wait_running_turn`: ``` ........ # This is the only bits of the entire function which access the TLS base register %fs. # It seems to have spilled the value of ruby_current_ec into %r13. 0x000055603d2e1cf8 <+136>: mov $0xffffffffffffff90,%rax 0x000055603d2e1cff <+143>: mov %fs:0x0,%r12 0x000055603d2e1d08 <+152>: add %rax,%r12 0x000055603d2e1d0b <+155>: mov %fs:(%rax),%r13 ........ # There's a call to coroutine_transfer, so after this point we're returned to on a # different thread 0x000055603d2e1e90 <+544>: call 0x55603d7fce84 <coroutine_transfer> # But nothing ever loads the address of ruby_current_ec from %fs again (i didn't trace # exactly the data flow from %r13 at 0x000055603d2e1d0b to here, but i assume it spilled # somewhere and now got loaded back into %r15 here). In any case, that means %r15 here # contains the value of ruby_current_ec from the _old_ thread, not the current one. 0x000055603d2e1e95 <+549>: mov %rbx,0x28(%r14) 0x000055603d2e1e99 <+553>: mov (%r12),%r15 0x000055603d2e1e9d <+557>: call 0x55603d33a010 <rb_current_ec_noinline> 0x000055603d2e1ea2 <+562>: cmp %rax,%r15 => 0x000055603d2e1ea5 <+565>: jne 0x55603d2e1f3a <thread_sched_wait_running_turn+714> ........ # assertion failure code path. 0x000055603d2e1f3a <+714>: lea 0x542c0c(%rip),%rdi # 0x55603d824b4d 0x000055603d2e1f41 <+721>: lea 0x542c12(%rip),%rdx # 0x55603d824b5a 0x000055603d2e1f48 <+728>: lea 0x542c28(%rip),%rcx # 0x55603d824b77 0x000055603d2e1f4f <+735>: mov $0x7a5,%esi 0x000055603d2e1f54 <+740>: call 0x55603d08d698 <rb_assert_failure> ``` if we look at the register values from `0x000055603d2e1ea2`: ``` (rr) print/x $rax $2 = 0x55603e159ad0 (rr) print/x $r15 $3 = 0x0 ``` So the value from `%rax` which came from `ruby_current_ec_noinline` is correctly the value of `ruby_current_ec` for this thread, and `%r15` contains a stale value from a previous thread. - Now, what can we _do_ about this, is a different question :/ There's a really good stackoverflow answer about it here: https://stackoverflow.com/questions/75592038/how-to-disable-clang-expressio…, but to summarise * longstanding GCC and Clang bugs for this exist and have been marked as WONTFIX (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=26461, https://github.com/llvm/llvm-project/issues/19551) * It's even worse than this EC problem - things like `errno` also might be incorrectly persisted across coroutine switches (so e.g. an inlined C library function could in theory set `errno` in another thread, for example) * C++ actually has coroutines now, so this _must_ work for those. Clang at least has fixed some TLS problems in their C++ coroutine implementation (https://github.com/llvm/llvm-project/issues/47179) Other than reimplementing all of our coroutine stuff on top of C++ coroutines, I'm not sure what else we can do. AFAICT there's no way to tell the compiler that we clobbered the `%fs` register because that's just not a thing in its model (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66631, but i assume clang is similar). Thoughts? For now I think my workaround is to disable M:N at build time when building with ASAN (or turn optimizations down). At least this isn't a problem with `Fiber` because we never move them across threads (probably for this reason in part). -- https://bugs.ruby-lang.org/
3 4
0 0
[ruby-core:120034] [Ruby master Bug#20917] redo/next in nested begin block causes wrong order of execution
by hoshiumiarata (Arata Hoshiumi) 30 Aug '26

30 Aug '26
Issue #20917 has been reported by hoshiumiarata (Arata Hoshiumi). ---------------------------------------- Bug #20917: redo/next in nested begin block causes wrong order of execution https://bugs.ruby-lang.org/issues/20917 * Author: hoshiumiarata (Arata Hoshiumi) * Status: Open * ruby -v: ruby 3.3.5 (2024-09-03 revision ef084cc8f4) [x86_64-darwin24] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- It seems that `redo`/`next` in a nested `begin` block can cause the wrong order of execution. For example: ```ruby for _ in [0] puts 0 begin puts 1 begin puts 2 redo ensure puts 3 end ensure puts 4 break end end ``` It prints: ``` 0 1 2 3 4 3 4 => nil ``` But I think it should print: ``` 0 1 2 3 4 => nil ``` Because execution order should be: 1. `puts 0` 2. `puts 1` 3. `puts 2` 4. `redo` 5. unwind to nested `ensure` block 6. `puts 3` 7. unwind to outer `ensure` block 8. `puts 4` 9. `break` 10. end of loop Interestingly enough, if we add an empty `rescue` block before any of the `ensure` blocks, then the execution order is correct. -- https://bugs.ruby-lang.org/
4 3
0 0
  • ← Newer
  • 1
  • 2
  • 3
  • 4
  • ...
  • 23
  • Older →

HyperKitty Powered by HyperKitty version 1.3.12.