Skip to content

Commit 65f0a44

Browse files
george-bitclaude
andcommitted
Fix segfault when Ruby coverage is enabled with Rails 8.1 ERB templates
v4.2.0 introduced a fix for incorrect line numbers in stack traces on Rails 8.1 by using negative lineno values (-1) in class_eval. However, negative line numbers cause segmentation faults when Ruby's Coverage module is enabled (e.g., when using SimpleCov in CI). This is a known Ruby bug: https://bugs.ruby-lang.org/issues/19363 The fix detects whether coverage is running via Coverage.running? and adapts the lineno value accordingly: - Coverage OFF: Use -1 (correct line numbers in stack traces) - Coverage ON: Use 1 (avoids segfault, line numbers off by ~2) Note: lineno=0 was also tested but causes the same segfault, so 1 is the minimum safe value when coverage is enabled. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 1722b70 commit 65f0a44

1 file changed

Lines changed: 14 additions & 6 deletions

File tree

lib/view_component/template.rb

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@ def initialize(component:, details:, lineno: nil, path: nil)
2121

2222
class File < Template
2323
def initialize(component:, details:, path:)
24-
# Rails 8.1 added a newline to the compiled ERB output in
25-
# https://github.com/rails/rails/pull/53731
24+
# Rails 8.1 added a newline to compiled ERB output (rails/rails#53731).
25+
# Use -1 to compensate for correct line numbers in stack traces.
26+
# However, negative line numbers cause segfaults when Ruby's coverage
27+
# is enabled (bugs.ruby-lang.org/issues/19363), so use 1 in that case.
2628
lineno =
2729
if Rails::VERSION::MAJOR >= 8 && Rails::VERSION::MINOR > 0 && details.handler == :erb
28-
- 1
30+
coverage_running? ? 1 : -1
2931
else
3032
0
3133
end
@@ -54,11 +56,13 @@ class Inline < Template
5456
def initialize(component:, inline_template:)
5557
details = ActionView::TemplateDetails.new(nil, inline_template.language.to_sym, nil, nil)
5658

57-
# Rails 8.1 added a newline to the compiled ERB output in
58-
# https://github.com/rails/rails/pull/53731
59+
# Rails 8.1 added a newline to compiled ERB output (rails/rails#53731).
60+
# Subtract 1 to compensate for correct line numbers in stack traces.
61+
# However, negative line numbers cause segfaults when Ruby's coverage
62+
# is enabled (bugs.ruby-lang.org/issues/19363), so skip the adjustment in that case.
5963
lineno =
6064
if Rails::VERSION::MAJOR >= 8 && Rails::VERSION::MINOR > 0 && details.handler == :erb
61-
inline_template.lineno - 1
65+
coverage_running? ? inline_template.lineno : inline_template.lineno - 1
6266
else
6367
inline_template.lineno
6468
end
@@ -126,6 +130,10 @@ def #{call_method_name}
126130
@component.define_method(safe_method_name, @component.instance_method(@call_method_name))
127131
end
128132

133+
def coverage_running?
134+
defined?(Coverage) && Coverage.running?
135+
end
136+
129137
def safe_method_name_call
130138
m = safe_method_name
131139
proc { send(m) }

0 commit comments

Comments
 (0)