Project

General

Profile

Bug #11071

Stack consistency error while using RSpec and Timecop

Added by jcoglan (James Coglan) over 5 years ago. Updated about 1 year ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
[ruby-core:<unknown>]

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

bug-11071.log (50.5 KB) bug-11071.log nobu (Nobuyoshi Nakada), 04/16/2015 07:22 AM

Related issues

Related to Ruby master - Bug #11451: MRI crashes with 'Stack inconsistency error' when a method which yields is called recursively in a particular wayClosedko1 (Koichi Sasada)Actions
#1

Updated by myronmarston (Myron Marston) over 5 years ago

There are two interesting things I've noticed about this:

  1. It does not happen on 2.1, so it appears to be a regression in 2.2.
  2. It appears to be related to to_proc. If you change jcoglan (James Coglan)'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.

#2

Updated by nobu (Nobuyoshi Nakada) over 5 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 5 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.

#4

Updated by alexdowad (Alex Dowad) about 5 years ago

This is fixed by the patch I just posted for #11451.

#5

Updated by usa (Usaku NAKAMURA) about 5 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
#6

Updated by jeremyevans0 (Jeremy Evans) about 1 year ago

  • Status changed from Open to Closed

Also available in: Atom PDF