Skip to content

Instantly share code, notes, and snippets.

@mbj
Last active September 28, 2017 17:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mbj/31163a8e712573877268 to your computer and use it in GitHub Desktop.
Save mbj/31163a8e712573877268 to your computer and use it in GitHub Desktop.
segfault.rb
class Foo
include Enumerable
def each(&block)
[].__send__(:each, &block)
rescue Exception
end
def more
to_a # any method from enumerable
[self]
end
end
def call(resource)
resource.more.each(&method(__method__))
end
Thread.new do
Kernel.catch(Exception.new) do
call(Foo.new)
end
end.join
# It is expected to:
# a) Raise a system stack error (expected)
# b) Segfault (Bug in MRI I'm hunting)
# c) Hang (Serve bug in MRI I'm hunting) please also check via strace / gdb if a segfault happened and the signal handler is trapped in a futex
# Context: https://github.com/mbj/mutant/issues/265
@gregkare
Copy link

Ubuntu 12.04 using Ruby 2.1.3 from the Brightbox PPA:

$ ruby segfault.rb
segfault.rb:23: stack level too deep (SystemStackError)
~$ ruby --version
ruby 2.1.3p242 (2014-09-19 revision 45877) [x86_64-linux-gnu]

@BRMatt
Copy link

BRMatt commented Oct 29, 2014

~ ❯❯❯ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux testing (jessie)
Release:    testing
Codename:   jessie
~ ❯❯❯ uname -a                                                                                 ⏎
Linux matt-desktop 3.2.0-4-amd64 #1 SMP Debian 3.2.63-2 x86_64 GNU/Linux
~ ❯❯❯ cat <<EOF | ruby                                                                         ⏎
pipe heredoc> class Foo
pipe heredoc>   include Enumerable
pipe heredoc> 
pipe heredoc>   def each(&block)
pipe heredoc>     [].__send__(:each, &block)
pipe heredoc>   rescue Exception
pipe heredoc>   end
pipe heredoc> 
pipe heredoc>   def more
pipe heredoc>     to_a # any method from enumerable
pipe heredoc>     [self]
pipe heredoc>   end
pipe heredoc> end
pipe heredoc> 
pipe heredoc> def call(resource)
pipe heredoc>   resource.more.each(&method(__method__))
pipe heredoc> end
pipe heredoc> 
pipe heredoc> Thread.new do
pipe heredoc>   Kernel.catch(Exception.new) do
pipe heredoc>     call(Foo.new)
pipe heredoc>   end
pipe heredoc> end.join
pipe heredoc> EOF
[1]    2066 done                cat <<<'' | 
       2067 segmentation fault  ruby
~ ❯❯❯ ruby --version                                                                           ⏎
ruby 2.0.0p353 (2013-11-22 revision 43784) [x86_64-linux]
~ ❯❯❯ cat <<EOF | ruby
class Foo
  include Enumerable

  def each(&block)
    [].__send__(:each, &block)
  rescue Exception
  end

  def more
    to_a # any method from enumerable
    [self]
  end
end

def call(resource)
  resource.more.each(&method(__method__))
end

Thread.new do
  Kernel.catch(Exception.new) do
    call(Foo.new)
  end
end.join
EOF
[1]    2265 done                cat <<<'' | 
       2266 segmentation fault  ruby
~ ❯❯❯ ruby --version                                                                           ⏎
ruby 2.1.3p242 (2014-09-19 revision 47630) [x86_64-linux]

@tjchambers
Copy link

ruby 2.1.3p242 (2014-09-19 revision 47630) [x86_64-darwin13.0]
Mac OS x 10.10

SystemStackError: stack level too deep
from /Users/tj/.rvm/rubies/ruby-2.1.3/lib/ruby/2.1.0/irb/workspace.rb:86

@phiggins
Copy link

pete@balloon:/tmp$ uname -a
Linux balloon 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
pete@balloon:/tmp$ for i in 1.9.3 2.1.2 2.1.3 ; do rvm $i do ruby -v segfault.rb ; done
ruby 1.9.3p547 (2014-05-14 revision 45962) [x86_64-linux]
segfault.rb:19: stack level too deep (SystemStackError)
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-linux]
Segmentation fault
ruby 2.1.3p242 (2014-09-19 revision 47630) [x86_64-linux]
segfault.rb:10: [BUG] vm_call_cfunc - cfp consistency error
ruby 2.1.3p242 (2014-09-19 revision 47630) [x86_64-linux]

Segmentation fault

Additionally, 2.0.0-p576 just hangs.

@postmodern
Copy link

Fedora Linux x86_64, compiled with ruby-install:

  • ruby-2.0.0-p353: stack level too deep (SystemStackError)
  • ruby-2.1.2(-p95): stack level too deep (SystemStackError)
  • ruby-2.1.3(-p242): hangs

This seems to imply the Segfault is due to the version of gcc or custom CFLAGS? Here is my gcc version:

gcc (GCC) 4.8.3 20140911 (Red Hat 4.8.3-7)

@pointlessone
Copy link

OS X 10.10 (14A389)

-=>> ruby --version
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-darwin13.0]

Just hangs. Can provide a spindump.

@jodosha
Copy link

jodosha commented Oct 30, 2014

% system_profiler SPSoftwareDataType -detailLevel mini
# ...
System Version: OS X 10.9.5 (13F34)
Kernel Version: Darwin 13.4.0

% gcc -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin13.4.0
Thread model: posix

% ruby-install --version
ruby-install: 0.4.3

% ruby -v
2.0.0p594 (2014-10-27) [x86_64-darwin13.4.0]
% ruby segfault.rb
segfault.rb:23: stack level too deep (SystemStackError)

% ruby -v
ruby 2.1.0p0 (2013-12-25 revision 44422) [x86_64-darwin13.0]
% ruby segfault.rb
(hangs)

% ruby -v
ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-darwin13.0]
% ruby segfault.rb
(hangs)

% ruby -v
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-darwin13.0]
% ruby segfault.rb
(hangs)

% ruby -v
ruby 2.1.3p242 (2014-09-19 revision 47630) [x86_64-darwin13.0]
% ruby segfault.rb
segfault.rb:23: stack level too deep (SystemStackError)

% ruby -v
ruby 2.1.4p265 (2014-10-27 revision 48166) [x86_64-darwin13.0]
% ruby segfault.rb
segfault.rb:23: stack level too deep (SystemStackError)

% ruby -v
ruby 2.2.0preview1 (2014-09-17 trunk 47616) [x86_64-darwin13]
% ruby segfault.rb
(hangs)

@plexus
Copy link

plexus commented Oct 30, 2014

Ubuntu 14.04
Kernel Linux lutze 3.13.0-39-generic #66-Ubuntu SMP Tue Oct 28 13:30:27 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2

1.9.3 to 2.1.2 : normal behaviour

ruby-1.9.3-p484
ruby 1.9.3p484 (2013-11-22) [x86_64-linux]
/home/arne/projects/ruby-tmp/00209.rb:19: stack level too deep (SystemStackError)
ruby-1.9.3-p545
ruby 1.9.3p545 (2014-02-24) [x86_64-linux]
/home/arne/projects/ruby-tmp/00209.rb:19: stack level too deep (SystemStackError)
ruby-1.9.3-p547
ruby 1.9.3p547 (2014-05-14) [x86_64-linux]
/home/arne/projects/ruby-tmp/00209.rb:19: stack level too deep (SystemStackError)
ruby-2.0.0-p451
ruby 2.0.0p451 (2014-02-24) [x86_64-linux]
/home/arne/projects/ruby-tmp/00209.rb:23: stack level too deep (SystemStackError)
ruby-2.1.1
ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-linux]
/home/arne/projects/ruby-tmp/00209.rb:23: stack level too deep (SystemStackError)
ruby-2.1.1-tco
ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-linux]
/home/arne/projects/ruby-tmp/00209.rb:23: stack level too deep (SystemStackError)
ruby-2.1.2
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-linux]
/home/arne/projects/ruby-tmp/00209.rb:23: stack level too deep (SystemStackError)

Getting a segfault on 2.1.3, 2.1.4, and trunk

ruby 2.1.3p242 (2014-09-19 revision 47630) [x86_64-linux]
ruby 2.1.4p265 (2014-10-27 revision 48166) [x86_64-linux]
ruby 2.2.0dev (2014-10-29 trunk 48188) [x86_64-linux]

@plexus
Copy link

plexus commented Oct 30, 2014

@skade
Copy link

skade commented Oct 30, 2014

I knew that never cleaning up would come in handy:

OS X 10.9.5, all rubies built with ruby-install

[ skade ~ ] chruby-exec ruby-1.9.3-p484 segfault.rb
chruby-exec: COMMAND required
[ skade ~ ] chruby-exec ruby-1.9.3-p484 ruby segfault.rb
chruby-exec: COMMAND required
[ skade ~ ] chruby-exec ruby-1.9.3-p484 -- ruby segfault.rb
segfault.rb:19: stack level too deep (SystemStackError)
[ skade ~ ] chruby-exec ruby-2.0.0-p247 -- ruby segfault.rb
segfault.rb:23: stack level too deep (SystemStackError)
[ skade ~ ] chruby-exec ruby-2.0.0-p353 -- ruby segfault.rb
segfault.rb:23: stack level too deep (SystemStackError)
[ skade ~ ] chruby-exec ruby-2.1.0 -- ruby segfault.rb
<hangs>
[ skade ~ ] chruby-exec ruby-2.1.1 -- ruby segfault.rb
<hangs>

gcc is clang by the way:

[ skade ~ ] gcc -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer//usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.0 (clang-600.0.51) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin13.4.0
Thread model: posix

dtruss output for ruby-2.1.0:

https://gist.github.com/skade/3baee907278ff602fce1

@mbj
Copy link
Author

mbj commented Oct 30, 2014

@ALL When it hangs, can you post an strace of the hanging process?

@skade
Copy link

skade commented Oct 30, 2014

@mbj: I used dtruss (OS X) and added a link to the gist with the output.

@mbj
Copy link
Author

mbj commented Oct 30, 2014

@skade, thx.

@plexus
Copy link

plexus commented Nov 4, 2014

Some more info

On trunk from a week ago, compiled with -O0, -O1, -O2, it would work correctly (SystemStackError). This is for this commit

commit 98ea62756142b6c9cc030e99b6d936d986ce463c
Author: nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date:   Wed Oct 29 12:13:26 2014 +0000

    parse.y: warn circular argument reference

    * parse.y (gettable_gen): warn circular argument reference, for
      transition from 2.1 and earlier.  [ruby-core:65990] [Bug #10314]

    git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48188 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

With -O3 it would segfault in rb_const_get (variable.c:2658) on this line

    if (tbl && st_lookup(tbl, (st_data_t)id, &val)) {

On current trunk

commit 2f00182634eaa0389b46322301795de475f46cec
Author: nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date:   Tue Nov 4 07:25:41 2014 +0000

    suppress warnings

    * vm.c (rb_vm_make_proc): cast to suppress warning by VC6.

    * ext/-test-/win32/console/attribute.c (console_set_attribute):
      ditto.

    git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48266 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

It works correctly with -O0 and -O2, gives a segfault with -O1, and hangs with -O3.

Straces of the two problematic runs:

@mbj
Copy link
Author

mbj commented Nov 13, 2014

I just tried with freshly released 2.1.5 and it still segfaults. :(

@mbj
Copy link
Author

mbj commented Jan 31, 2015

This problem was probably solved with: ruby/ruby@8fe95fe

@kbrock
Copy link

kbrock commented Sep 22, 2015

2.2.3 and 2.2.2 give me the same results.

ruby segfault.rb 
segfault.rb:10:in `to_a': stack level too deep (SystemStackError)
    from segfault.rb:10:in `more'
    from segfault.rb:16:in `call'
    from segfault.rb:16:in `each'
    from segfault.rb:16:in `call'
    from segfault.rb:16:in `each'
    from segfault.rb:16:in `call'
    from segfault.rb:16:in `each'
    from segfault.rb:16:in `call'
     ... 1189 levels...
    from segfault.rb:16:in `call'
    from segfault.rb:21:in `block (2 levels) in <main>'
    from segfault.rb:20:in `catch'
    from segfault.rb:20:in `block in <main>'
ruby --version
ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-darwin14]

of note, 2.3dev just hangs for me.

@mathieujobin
Copy link

mathieujobin commented Sep 28, 2017

[mathieu@hz550 loyalty]$ rvm use 2.2.8
Using /home/mathieu/.rvm/gems/ruby-2.2.8
[mathieu@hz550 loyalty]$ ruby  segfault.rb
segfault.rb:10:in `to_a': stack level too deep (SystemStackError)
        from segfault.rb:10:in `more'
        from segfault.rb:16:in `call'
        from segfault.rb:16:in `each'
        from segfault.rb:16:in `call'
        from segfault.rb:16:in `each'
        from segfault.rb:16:in `call'
        from segfault.rb:16:in `each'
        from segfault.rb:16:in `call'
         ... 1103 levels...
        from segfault.rb:16:in `call'
        from segfault.rb:21:in `block (2 levels) in <main>'
        from segfault.rb:20:in `catch'
        from segfault.rb:20:in `block in <main>'
[mathieu@hz550 loyalty]$ ruby -v 
ruby 2.2.8p477 (2017-09-14 revision 59906) [x86_64-linux]
[mathieu@hz550 loyalty]$ rvm use 2.3.5
Using /home/mathieu/.rvm/gems/ruby-2.3.5
[mathieu@hz550 loyalty]$ ruby  segfault.rb
segfault.rb:10:in `to_a': stack level too deep (SystemStackError)
        from segfault.rb:10:in `more'
        from segfault.rb:16:in `call'
        from segfault.rb:16:in `each'                                                                                                                                                
        from segfault.rb:16:in `call'                                                                                                                                                
        from segfault.rb:16:in `each'                                                                                                                                                
        from segfault.rb:16:in `call'                                                                                                                                                
        from segfault.rb:16:in `each'                                                                                                                                                
        from segfault.rb:16:in `call'                                                                                                                                                
         ... 809 levels...                                                                                                                                                           
        from segfault.rb:16:in `call'                                                                                                                                                
        from segfault.rb:21:in `block (2 levels) in <main>'                                                                                                                          
        from segfault.rb:20:in `catch'                                                                                                                                               
        from segfault.rb:20:in `block in <main>'                                                                                                                                     
[mathieu@hz550 loyalty]$ rvm use 2.4.2
Using /home/mathieu/.rvm/gems/ruby-2.4.2
[mathieu@hz550 loyalty]$ ruby  segfault.rb
segfault.rb:10: [BUG] vm_call_cfunc - cfp consistency error
ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-linux]

-- Control frame information -----------------------------------------------
Segmentation fault (core dumped)
[mathieu@hz550 loyalty]$ 

ArchLinux 64bit
Linux hz550 4.12.12-1-ARCH #1 SMP PREEMPT Sun Sep 10 09:41:14 CEST 2017 x86_64 GNU/Linux

on debian 14.04 I am getting segfault.rb:10: [BUG] vm_call_cfunc - cfp consistency error on 2.2.8

@mathieujobin
Copy link

mathieujobin commented Sep 28, 2017

mathieu@ubuntu-1404 (i-123):~$ ruby segfault.rb 
Segmentation fault (core dumped)                                                                                                                                                     
mathieu@ubuntu-1404 (i-123):~$    

with brighbox compiled packages

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment