From: "amalrik (amalrik maia) via ruby-core" Date: 2026-10-14T23:23:53+00:00 Subject: [ruby-core:127114] [Ruby Bug#22439] Segfault in `Thread::Backtrace::Location#syntax_tree` (via `Exception#detailed_message` / error_highlight) when called from multiple Ractors Issue #22439 has been updated by amalrik (amalrik maia). mame (Yusuke Endoh) wrote in #note-3: > Thank you for the report! > > I could reproduce the SEGV only with GCC 16 (GCC 13 and 15 did not reproduce it). Are you also using GCC 16 to build Ruby? > > This ticket contained two different problems, so I have split it into: > > * #22440: SEGV when referencing an autoload constant from multiple Ractors (`Ruby::Prism` is autoloaded, which caused the crash here) > * #22442: the lazy loading of error_highlight etc. is skipped in threads and Ractors (which is why the snippet was not shown) > > If possible, I'd appreciate it if you could test with both patches attached to those tickets applied together. Thank you for the quick analysis and for splitting the ticket! Yes, I'm using GCC 16. Both 4.1 builds I reported were compiled locally on Arch Linux: ``` ruby 4.1.0preview1 (2026-10-11 master 2d08b5f42f) +PRISM [x86_64-linux] ruby 4.1.0dev (2026-10-14T14:33:24Z master b709bdb3e3) +PRISM [x86_64-linux] CC: gcc (GCC) 16.2.1 20260810, optflags -O3 -fno-fast-math ``` Two corrections to my original report, sorry about them: - The "Also seen on Ubuntu 24.04, AMD EPYC Genoa" line was wrong. I never ran this reproducer on that machine. - The 4.0.6/4.0.7 binaries I used as the "works" baseline were prebuilt with GCC 10. So the version comparison in the report is confounded by the compiler, which is consistent with your finding. I tested both patches applied together: https://github.com/ruby/ruby/pull/19348 and https://github.com/ruby/ruby/pull/19352, cherry-picked onto master 3d168b1. I built with the same GCC 16.2.1 and ran each script N times: | Script | master b709bdb3e3 (no patches) | master 3d168b1 + both patches | |---|---|---| | #22440 reproducer (autoload constant from 8 Ractors) | 10/10 SEGV | 10/10 ok | | #22439 `detailed_message` from 2 Ractors | 10/10 SEGV | 10/10 ok | | #22439 `e.backtrace_locations.first.syntax_tree` from 2 Ractors | 1/10 SEGV | 10/10 ok | | #22442 snippet present in both Ractors (`nil.upcase` in 2 Ractors) | not testable (SEGV) | 5/5 runs, snippet in both | So with both patches, everything in this ticket is fixed on my machine. Thanks! ---------------------------------------- Bug #22439: Segfault in `Thread::Backtrace::Location#syntax_tree` (via `Exception#detailed_message` / error_highlight) when called from multiple Ractors https://bugs.ruby-lang.org/issues/22439#change-119514 * Author: amalrik (amalrik maia) * Status: Open * ruby -v: ruby 4.1.0dev (2026-10-14T14:33:24Z master b709bdb3e3) +PRISM [x86_64-linux] * Backport: 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- Calling `Exception#detailed_message` concurrently from two or more Ractors crashes the VM with `[BUG] Segmentation fault` on 4.1.0-preview1 and current master. The same script works on 4.0.6 and 4.0.7. ### Reproduction No gems are involved; error_highlight is loaded by default. ```ruby n = Integer(ARGV[0] || 2) rs = Array.new(n) do |i| Ractor.new(i) do |id| 500.times do |k| begin raise ArgumentError, "falha #{id}-#{k}" rescue => e e.detailed_message(highlight: false) end end :ok end end p rs.map(&:value) ``` ``` $ ruby repro.rb :374: [BUG] Segmentation fault at 0x0000000000000030 ``` | Version | Result | | ---------------------------- | ------------------------------------------------------------ | | 4.0.6, 4.0.7 | `[:ok, :ok]` (8/8 runs) | | 4.1.0-preview1 (2d08b5f42f) | segfault in 4/4 runs with 2 Ractors and 8/8 with 8 Ractors; no crash with 1 Ractor | | 4.1.0dev master (b709bdb3e3) | segfault 6/6 | ### Backtrace (master) ``` :374: [BUG] Segmentation fault at 0x0000000000000030 -- Ruby level backtrace information ---------------------------------------- repro.rb:8:in 'detailed_message' .../lib/ruby/4.1.0+5/error_highlight/core_ext.rb:43:in 'detailed_message' .../lib/ruby/4.1.0+5/error_highlight/core_ext.rb:34:in 'generate_snippet' .../lib/ruby/4.1.0+5/error_highlight/base.rb:57:in 'spot' .../lib/ruby/4.1.0+5/error_highlight/base.rb:77:in 'find_node_from_loc' :478:in 'syntax_tree' :374:in 'syntax_tree' -- C level backtrace information ------------------------------------------- rb_vm_bugreport rb_ec_ractor_ptr / rb_current_execution_context / rb_current_ractor_raw / rb_current_ractor vm_ic_update rb_vm_opt_getconstant_path vm_exec_core rb_vm_exec thread_start_func_2 ``` The full output is attached (`crash-output-master.txt`). ### Additional observations 1. **The crash is reachable without error_highlight.** Calling `e.backtrace_locations.first.syntax_tree` inside `rescue` in 2 Ractors gives the same crash and stack. It crashed 1/3 runs on master and 0/3 on preview1, so the `detailed_message` script above is the more reliable reproducer. 2. **Some things that look similar do not crash.** - `caller_locations(0, 1).first.syntax_tree` in 2 Ractors works. - `Ruby::Prism.parse("1 + 1")` in 2 Ractors works. So the problem seems specific to backtrace locations taken from an exception, while the constant cache in `ast.rb` is updated from a non-main Ractor. 3. **With a single Ractor there is no crash, but error_highlight output regresses.** Inside the Ractor, `detailed_message` returns only the message, without the snippet: ```ruby r = Ractor.new do begin nil.upcase rescue => e e.detailed_message(highlight: false) end end puts r.value # 4.0.7: undefined method 'upcase' for nil (NoMethodError)\n\n nil.upcase\n ^^^^^^^ # 4.1: undefined method 'upcase' for nil (NoMethodError) ``` On 4.1 the snippet is still shown in the main Ractor. 4. **This is easy to hit in practice.** Any library that logs exceptions with `detailed_message` from inside Ractors can crash the process. I found it with the `async` gem, whose task-failure logging (via the `console` gem) calls `detailed_message`, running one reactor per Ractor. On 4.0.6 that same setup hangs instead of crashing; I have not diagnosed the 4.0.6 hang. ### Related (but different) issues - #22386: segfault when a Ractor helper thread reports an exception during teardown. It was fixed before preview1, and this still reproduces on preview1 and master. - #21183: error_highlight raising `Ractor::IsolationError` in non-main Ractors (fixed in 2025). ### Environment and context - Linux x86_64 (kernel 7.2, AMD Ryzen 7 5700U, 8C/16T). Also seen on Ubuntu 24.04, AMD EPYC Genoa (KVM). - These scripts come out of a benchmark study comparing threads, Ractors and Fibers on Ruby 4.0 and 4.1. The code, raw results and other Ractor findings (I/O concurrency cap on 4.0.x, socket hangs on 4.0.x) are public at: https://github.com/amalrik/ruby-ractors-study. The reproducers for this issue are in `upstream/ruby-4.1-detailed-message-ractors/` -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/