Bug #11071
closedStack consistency error while using RSpec and Timecop
Description
I have this Gemfile:
source 'https://rubygems.org'
ruby '2.2.2'
gem 'rspec'
gem 'timecop'
producing this Gemfile.lock:
GEM
remote: https://rubygems.org/
specs:
diff-lcs (1.2.5)
rspec (3.2.0)
rspec-core (~> 3.2.0)
rspec-expectations (~> 3.2.0)
rspec-mocks (~> 3.2.0)
rspec-core (3.2.3)
rspec-support (~> 3.2.0)
rspec-expectations (3.2.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.2.0)
rspec-mocks (3.2.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.2.0)
rspec-support (3.2.2)
timecop (0.7.3)
PLATFORMS
ruby
DEPENDENCIES
rspec
timecop
and this test file:
# timecop_spec.rb
require 'timecop'
describe Timecop do
around do |example|
Timecop.travel(Time.parse('2015-01-01 06:30:00'), &example)
end
it 'sets the current time' do
Timecop.travel(Time.parse('2015-01-01 09:30:00')) {}
end
end
When I run bundle exec rspec -c timecop_spec.rb
, this is the output:
/home/jcoglan/projects/futurelearn/timecop-segfault/.bundle/ruby/2.2.0/gems/timecop-0.7.3/lib/timecop/timecop.rb:142: [BUG] Stack consistency error (sp: 145, bp: 144)
ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
Files
Updated by myronmarston (Myron Marston) over 9 years ago
There are two interesting things I've noticed about this:
- It does not happen on 2.1, so it appears to be a regression in 2.2.
- It appears to be related to
to_proc
. If you change @jcoglan's example to use an around hook like this:
around do |example|
Timecop.travel(Time.parse('2015-01-01 06:30:00')) { example.run }
end
...the segfault does not happen. The to_proc
definition is here, FWIW:
https://github.com/rspec/rspec-core/blob/v3.2.3/lib/rspec/core/example.rb#L244-L255
If some ruby core folks want to work on this and would like a more isolated example (e.g. an example that triggers the same bug w/o loading RSpec itself), let me know and I can try to pare it down to something more minimal.
Updated by nobu (Nobuyoshi Nakada) over 9 years ago
- Description updated (diff)
- File bug-11071.log bug-11071.log added
- Subject changed from Segfault while using RSpec and Timecop to Stack consistency error while using RSpec and Timecop
- Backport changed from 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN to 2.0.0: DONTNEED, 2.1: DONTNEED, 2.2: REQUIRED
Reproduced with the trunk.
class E
def initialize(&proc)
@proc = proc
end
def run(a)
@proc.call
end
def to_proc
method(:run).to_proc
end
end
class T
def doit
yield nil
end
end
t = T.new
e = E.new {t.doit {}}
t.doit(&e)
Updated by nobu (Nobuyoshi Nakada) over 9 years ago
Possibly shortest code.
def doit
yield nil
end
doit(&proc {doit {}}.method(:call))
But it doesn't happen, if the inner block has a single argument or arbitrary number arguments *
.
Oppositely, it's similar but sp
is less than bp
when the arguments are more than one.
And it seems the point to reenter the same method doit
.
Updated by alexdowad (Alex Dowad) about 9 years ago
This is fixed by the patch I just posted for #11451.
Updated by usa (Usaku NAKAMURA) about 9 years ago
- Related to Bug #11451: MRI crashes with 'Stack inconsistency error' when a method which yields is called recursively in a particular way added
Updated by jeremyevans0 (Jeremy Evans) over 5 years ago
- Status changed from Open to Closed