Project

General

Profile

Actions

Bug #15985

closed

Segmentation Fault exception when using dot-colon method reference on literals

Added by maciej.mensfeld (Maciej Mensfeld) almost 5 years ago. Updated almost 5 years ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 2.7.0dev (2019-07-04T09:54:50Z master 265b9a0edf) [x86_64-linux] last_commit=Parse key sequence more strictly
[ruby-core:93540]

Description

I have a simple script that actually does nothing:

nil.:|;1

or

:|.:!;:|

When I run it with make run for miniruby or I run it with the full built master.

I get a segmentation fault as followed for 95% of executions. From time to time, script runs ok.

[BUG] Segmentation fault at 0x0000000000000000
ruby 2.7.0dev (2019-07-04T09:54:50Z master 265b9a0edf) [x86_64-linux]

-- Control frame information -----------------------------------------------
c:0001 p:---- s:0004 E:001700 (none) [FINISH]


-- Machine register context ------------------------------------------------
 RIP: 0x00007fecaf9afb5c RBP: 0x0000556a686d36b8 RSP: 0x00007ffd041ea3f0
 RAX: 0x0000000000000018 RBX: 0x0000000000000000 RCX: 0x0000000000000000
 RDX: 0x0000000000000010 RDI: 0x0000556a686d36b8 RSI: 0x0000000000000038
  R8: 0x0000000000000000  R9: 0x0000556a6876bdd0 R10: 0x0000000000000000
 R11: 0x00007fecaf7f2300 R12: 0x0000556a6874f330 R13: 0x0000556a68a32398
 R14: 0x0000000000000000 R15: 0x00007fecafec4010 EFL: 0x0000000000010206

-- C level backtrace information -------------------------------------------
/workdir/build/../install/lib/libruby.so.2.7(rb_vm_bugreport+0x769) [0x7fecaf9ba7f9] ../ruby/vm_dump.c:707
/workdir/build/../install/lib/libruby.so.2.7(rb_bug_context+0xe7) [0x7fecaf7e57a7] ../ruby/error.c:599
/workdir/build/../install/lib/libruby.so.2.7(sigsegv+0x42) [0x7fecaf920fa2] ../ruby/signal.c:997
/lib/x86_64-linux-gnu/libc.so.6(0x7fecaf370f20) [0x7fecaf370f20]
/workdir/build/../install/lib/libruby.so.2.7(rb_vm_call0+0x2ac) [0x7fecaf9afb5c] ../ruby/vm_insnhelper.c:288
/workdir/build/../install/lib/libruby.so.2.7(rb_get_message+0x14) [0x7fecaf7e60d4] ../ruby/error.c:991
/workdir/build/../install/lib/libruby.so.2.7(rb_ec_error_print+0x396) [0x7fecaf7f1566] ../ruby/eval_error.c:363
/workdir/build/../install/lib/libruby.so.2.7(error_handle+0x181) [0x7fecaf7f1eb1] ../ruby/eval_error.c:79
/workdir/build/../install/lib/libruby.so.2.7(ruby_cleanup+0x1d7) [0x7fecaf7f2997] ../ruby/eval.c:212
/workdir/build/../install/lib/libruby.so.2.7(ruby_run_node+0x35) [0x7fecaf7f2c75] ../ruby/eval.c:318
/workdir/install/bin/ruby(main+0x6f) [0x556a67e0ea3f] ../ruby/main.c:42

-- Other runtime information -----------------------------------------------

* Loaded script: ../ruby/test.rb

* Loaded features:

    0 enumerator.so
    1 thread.rb
    2 rational.so
    3 complex.so
    4 /workdir/install/lib/ruby/2.7.0/x86_64-linux/enc/encdb.so
    5 /workdir/install/lib/ruby/2.7.0/x86_64-linux/enc/trans/transdb.so
    6 /workdir/install/lib/ruby/2.7.0/x86_64-linux/rbconfig.rb
    7 /workdir/install/lib/ruby/2.7.0/rubygems/compatibility.rb
    8 /workdir/install/lib/ruby/2.7.0/rubygems/defaults.rb
    9 /workdir/install/lib/ruby/2.7.0/rubygems/deprecate.rb
   10 /workdir/install/lib/ruby/2.7.0/rubygems/errors.rb
   11 /workdir/install/lib/ruby/2.7.0/rubygems/path_support.rb
   12 /workdir/install/lib/ruby/2.7.0/rubygems/version.rb
   13 /workdir/install/lib/ruby/2.7.0/rubygems/requirement.rb
   14 /workdir/install/lib/ruby/2.7.0/rubygems/platform.rb
   15 /workdir/install/lib/ruby/2.7.0/rubygems/basic_specification.rb
   16 /workdir/install/lib/ruby/2.7.0/rubygems/stub_specification.rb
   17 /workdir/install/lib/ruby/2.7.0/delegate.rb
   18 /workdir/install/lib/ruby/2.7.0/uri/rfc2396_parser.rb
   19 /workdir/install/lib/ruby/2.7.0/uri/rfc3986_parser.rb
   20 /workdir/install/lib/ruby/2.7.0/uri/common.rb
   21 /workdir/install/lib/ruby/2.7.0/uri/generic.rb
   22 /workdir/install/lib/ruby/2.7.0/uri/file.rb
   23 /workdir/install/lib/ruby/2.7.0/uri/ftp.rb
   24 /workdir/install/lib/ruby/2.7.0/uri/http.rb
   25 /workdir/install/lib/ruby/2.7.0/uri/https.rb
   26 /workdir/install/lib/ruby/2.7.0/uri/ldap.rb
   27 /workdir/install/lib/ruby/2.7.0/uri/ldaps.rb
   28 /workdir/install/lib/ruby/2.7.0/uri/mailto.rb
   29 /workdir/install/lib/ruby/2.7.0/uri.rb
   30 /workdir/install/lib/ruby/2.7.0/rubygems/util.rb
   31 /workdir/install/lib/ruby/2.7.0/rubygems/text.rb
   32 /workdir/install/lib/ruby/2.7.0/rubygems/user_interaction.rb
   33 /workdir/install/lib/ruby/2.7.0/rubygems/specification_policy.rb
   34 /workdir/install/lib/ruby/2.7.0/rubygems/util/list.rb
   35 /workdir/install/lib/ruby/2.7.0/x86_64-linux/stringio.so
   36 /workdir/install/lib/ruby/2.7.0/rubygems/specification.rb
   37 /workdir/install/lib/ruby/2.7.0/rubygems/exceptions.rb
   38 /workdir/install/lib/ruby/2.7.0/rubygems/bundler_version_finder.rb
   39 /workdir/install/lib/ruby/2.7.0/rubygems/dependency.rb
   40 /workdir/install/lib/ruby/2.7.0/rubygems/core_ext/kernel_gem.rb
   41 /workdir/install/lib/ruby/2.7.0/monitor.rb
   42 /workdir/install/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb
   43 /workdir/install/lib/ruby/2.7.0/rubygems/core_ext/kernel_warn.rb
   44 /workdir/install/lib/ruby/2.7.0/rubygems.rb

* Process memory map:

556a67e0e000-556a67e0f000 r-xp 00000000 fd:01 18780508                   /workdir/install/bin/ruby
556a6800e000-556a6800f000 r--p 00000000 fd:01 18780508                   /workdir/install/bin/ruby
556a6800f000-556a68010000 rw-p 00001000 fd:01 18780508                   /workdir/install/bin/ruby
556a686d1000-556a68b2c000 rw-p 00000000 00:00 0                          [heap]
7feca9e39000-7fecaa029000 r--s 00000000 fd:01 9179778                    /lib/x86_64-linux-gnu/libc-2.27.so
7fecaa029000-7fecaa71b000 rw-p 00000000 00:00 0 
7fecaa71b000-7fecaaf61000 r--s 00000000 fd:01 18125723                   /workdir/install/lib/libruby.so.2.7.0
7fecaaf61000-7fecaaf78000 r-xp 00000000 fd:01 9175247                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7fecaaf78000-7fecab177000 ---p 00017000 fd:01 9175247                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7fecab177000-7fecab178000 r--p 00016000 fd:01 9175247                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7fecab178000-7fecab179000 rw-p 00017000 fd:01 9175247                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7fecab179000-7fecab182000 r-xp 00000000 fd:01 18125747                   /workdir/install/lib/ruby/2.7.0/x86_64-linux/stringio.so
7fecab182000-7fecab381000 ---p 00009000 fd:01 18125747                   /workdir/install/lib/ruby/2.7.0/x86_64-linux/stringio.so
7fecab381000-7fecab382000 r--p 00008000 fd:01 18125747                   /workdir/install/lib/ruby/2.7.0/x86_64-linux/stringio.so
7fecab382000-7fecab383000 rw-p 00009000 fd:01 18125747                   /workdir/install/lib/ruby/2.7.0/x86_64-linux/stringio.so
7fecab383000-7fecab385000 r-xp 00000000 fd:01 18125817                   /workdir/install/lib/ruby/2.7.0/x86_64-linux/enc/trans/transdb.so
7fecab385000-7fecab585000 ---p 00002000 fd:01 18125817                   /workdir/install/lib/ruby/2.7.0/x86_64-linux/enc/trans/transdb.so
7fecab585000-7fecab586000 r--p 00002000 fd:01 18125817                   /workdir/install/lib/ruby/2.7.0/x86_64-linux/enc/trans/transdb.so
7fecab586000-7fecab587000 rw-p 00003000 fd:01 18125817                   /workdir/install/lib/ruby/2.7.0/x86_64-linux/enc/trans/transdb.so
7fecab587000-7fecab589000 r-xp 00000000 fd:01 18125824                   /workdir/install/lib/ruby/2.7.0/x86_64-linux/enc/encdb.so
7fecab589000-7fecab788000 ---p 00002000 fd:01 18125824                   /workdir/install/lib/ruby/2.7.0/x86_64-linux/enc/encdb.so
7fecab788000-7fecab789000 r--p 00001000 fd:01 18125824                   /workdir/install/lib/ruby/2.7.0/x86_64-linux/enc/encdb.so
7fecab789000-7fecab78a000 rw-p 00002000 fd:01 18125824                   /workdir/install/lib/ruby/2.7.0/x86_64-linux/enc/encdb.so
7fecab78a000-7fecad793000 rw-p 00000000 00:00 0 
7fecad793000-7fecae293000 r--p 00000000 fd:01 10230382                   /usr/lib/locale/locale-archive
7fecae293000-7fecae430000 r-xp 00000000 fd:01 9179841                    /lib/x86_64-linux-gnu/libm-2.27.so
7fecae430000-7fecae62f000 ---p 0019d000 fd:01 9179841                    /lib/x86_64-linux-gnu/libm-2.27.so
7fecae62f000-7fecae630000 r--p 0019c000 fd:01 9179841                    /lib/x86_64-linux-gnu/libm-2.27.so
7fecae630000-7fecae631000 rw-p 0019d000 fd:01 9179841                    /lib/x86_64-linux-gnu/libm-2.27.so
7fecae631000-7fecae63a000 r-xp 00000000 fd:01 9179788                    /lib/x86_64-linux-gnu/libcrypt-2.27.so
7fecae63a000-7fecae839000 ---p 00009000 fd:01 9179788                    /lib/x86_64-linux-gnu/libcrypt-2.27.so
7fecae839000-7fecae83a000 r--p 00008000 fd:01 9179788                    /lib/x86_64-linux-gnu/libcrypt-2.27.so
7fecae83a000-7fecae83b000 rw-p 00009000 fd:01 9179788                    /lib/x86_64-linux-gnu/libcrypt-2.27.so
7fecae83b000-7fecae869000 rw-p 00000000 00:00 0 
7fecae869000-7fecae86c000 r-xp 00000000 fd:01 9179801                    /lib/x86_64-linux-gnu/libdl-2.27.so
7fecae86c000-7fecaea6b000 ---p 00003000 fd:01 9179801                    /lib/x86_64-linux-gnu/libdl-2.27.so
7fecaea6b000-7fecaea6c000 r--p 00002000 fd:01 9179801                    /lib/x86_64-linux-gnu/libdl-2.27.so
7fecaea6c000-7fecaea6d000 rw-p 00003000 fd:01 9179801                    /lib/x86_64-linux-gnu/libdl-2.27.so
7fecaea6d000-7fecaeaec000 r-xp 00000000 fd:01 10231846                   /usr/lib/x86_64-linux-gnu/libgmp.so.10.3.2
7fecaeaec000-7fecaecec000 ---p 0007f000 fd:01 10231846                   /usr/lib/x86_64-linux-gnu/libgmp.so.10.3.2
7fecaecec000-7fecaeced000 r--p 0007f000 fd:01 10231846                   /usr/lib/x86_64-linux-gnu/libgmp.so.10.3.2
7fecaeced000-7fecaecee000 rw-p 00080000 fd:01 10231846                   /usr/lib/x86_64-linux-gnu/libgmp.so.10.3.2
7fecaecee000-7fecaecf5000 r-xp 00000000 fd:01 9179919                    /lib/x86_64-linux-gnu/librt-2.27.so
7fecaecf5000-7fecaeef4000 ---p 00007000 fd:01 9179919                    /lib/x86_64-linux-gnu/librt-2.27.so
7fecaeef4000-7fecaeef5000 r--p 00006000 fd:01 9179919                    /lib/x86_64-linux-gnu/librt-2.27.so
7fecaeef5000-7fecaeef6000 rw-p 00007000 fd:01 9179919                    /lib/x86_64-linux-gnu/librt-2.27.so
7fecaeef6000-7fecaef10000 r-xp 00000000 fd:01 9179911                    /lib/x86_64-linux-gnu/libpthread-2.27.so
7fecaef10000-7fecaf10f000 ---p 0001a000 fd:01 9179911                    /lib/x86_64-linux-gnu/libpthread-2.27.so
7fecaf10f000-7fecaf110000 r--p 00019000 fd:01 9179911                    /lib/x86_64-linux-gnu/libpthread-2.27.so
7fecaf110000-7fecaf111000 rw-p 0001a000 fd:01 9179911                    /lib/x86_64-linux-gnu/libpthread-2.27.so
7fecaf111000-7fecaf115000 rw-p 00000000 00:00 0 
7fecaf115000-7fecaf131000 r-xp 00000000 fd:01 9179950                    /lib/x86_64-linux-gnu/libz.so.1.2.11
7fecaf131000-7fecaf330000 ---p 0001c000 fd:01 9179950                    /lib/x86_64-linux-gnu/libz.so.1.2.11
7fecaf330000-7fecaf331000 r--p 0001b000 fd:01 9179950                    /lib/x86_64-linux-gnu/libz.so.1.2.11
7fecaf331000-7fecaf332000 rw-p 0001c000 fd:01 9179950                    /lib/x86_64-linux-gnu/libz.so.1.2.11
7fecaf332000-7fecaf519000 r-xp 00000000 fd:01 9179778                    /lib/x86_64-linux-gnu/libc-2.27.so
7fecaf519000-7fecaf719000 ---p 001e7000 fd:01 9179778                    /lib/x86_64-linux-gnu/libc-2.27.so
7fecaf719000-7fecaf71d000 r--p 001e7000 fd:01 9179778                    /lib/x86_64-linux-gnu/libc-2.27.so
7fecaf71d000-7fecaf71f000 rw-p 001eb000 fd:01 9179778                    /lib/x86_64-linux-gnu/libc-2.27.so
7fecaf71f000-7fecaf723000 rw-p 00000000 00:00 0 
7fecaf723000-7fecafab4000 r-xp 00000000 fd:01 18125723                   /workdir/install/lib/libruby.so.2.7.0
7fecafab4000-7fecafcb3000 ---p 00391000 fd:01 18125723                   /workdir/install/lib/libruby.so.2.7.0
7fecafcb3000-7fecafcb9000 r--p 00390000 fd:01 18125723                   /workdir/install/lib/libruby.so.2.7.0
7fecafcb9000-7fecafcbc000 rw-p 00396000 fd:01 18125723                   /workdir/install/lib/libruby.so.2.7.0
7fecafcbc000-7fecafcce000 rw-p 00000000 00:00 0 
7fecafcce000-7fecafcf5000 r-xp 00000000 fd:01 9179750                    /lib/x86_64-linux-gnu/ld-2.27.so
7fecafd0b000-7fecafec9000 rw-p 00000000 00:00 0 
7fecafecb000-7fecafef3000 r--s 00000000 fd:01 18780508                   /workdir/install/bin/ruby
7fecafef3000-7fecafef5000 rw-p 00000000 00:00 0 
7fecafef5000-7fecafef6000 r--p 00027000 fd:01 9179750                    /lib/x86_64-linux-gnu/ld-2.27.so
7fecafef6000-7fecafef7000 rw-p 00028000 fd:01 9179750                    /lib/x86_64-linux-gnu/ld-2.27.so
7fecafef7000-7fecafef8000 rw-p 00000000 00:00 0 
7ffd039ef000-7ffd041ee000 rw-p 00000000 00:00 0                          [stack]
7ffd041f8000-7ffd041fb000 r--p 00000000 00:00 0                          [vvar]
7ffd041fb000-7ffd041fd000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

In order to reproduce it just run the code that I pasted above couple times.

In order to always make it crush one can just:

1000.times { |i| p i+1; eval 'nil.:|;1' }

I was able to get max to the 3rd iteration.


Files

methodref-literal-compile-fix.patch (1.54 KB) methodref-literal-compile-fix.patch jeremyevans0 (Jeremy Evans), 07/04/2019 10:30 PM
Actions #1

Updated by maciej.mensfeld (Maciej Mensfeld) almost 5 years ago

  • Description updated (diff)
Actions #2

Updated by maciej.mensfeld (Maciej Mensfeld) almost 5 years ago

  • Subject changed from Segmentation Fault exception when using dot-colon method reference on nil to Segmentation Fault exception when using dot-colon method reference on literals
  • Description updated (diff)

Updated by jeremyevans0 (Jeremy Evans) almost 5 years ago

I can reproduce this. Here's a backtrace:

Thread 1 received signal SIGSEGV, Segmentation fault. 
0x000006441ce6cdcd in check_funcall_callable (ec=0x643ddd44e48, me=0x64472043dc0) at ./vm_eval.c:365
365         return rb_method_call_status(ec, me, CALL_FCALL, ec->cfp->self) == MISSING_NONE;
(gdb) bt              
#0  0x000006441ce6cdcd in check_funcall_callable (ec=0x643ddd44e48, me=0x64472043dc0) at ./vm_eval.c:365
#1  0x000006441ce6cc2b in rb_check_funcall_default (recv=6888293656040, mid=7921, argc=0, argv=0x0, def=52) at ./vm_eval.c:427
#2  0x000006441ce6cb80 in rb_check_funcall (recv=6888293656040, mid=7921, argc=0, argv=0x0) at ./vm_eval.c:412
#3  0x000006441cbefea5 in rb_get_message (exc=6888293656040) at error.c:991
#4  0x000006441cbf9091 in rb_ec_error_print (ec=0x643ddd44e48, errinfo=6888293656040) at ./eval_error.c:363
#5  0x000006441cbfa097 in error_print (ec=0x643ddd44e48) at ./eval_error.c:79
#6  0x000006441cbf9d44 in error_handle (ex=8) at ./eval_error.c:485
#7  0x000006441cbfa963 in ruby_cleanup (ex=8) at eval.c:212
#8  0x000006441cbfafc4 in ruby_run_node (n=0x6443d750008) at eval.c:318
#9  0x000006417fbe93bb in main (argc=3, argv=0x7f7ffffdbe18) at ./main.c:42

Running other times, I've seen the ex argument to ruby_cleanup be 3, 6, 8, indicating that there is already an error before ruby_cleanup is called.

This appears to be a bug in the iseq compiler for the code. It is parsed correctly:

$ ruby --dump=parsetree -e 'nil.:|;1'
###########################################################
## Do NOT use this node dump for any purpose other than  ##
## debug and research.  Compatibility is not guaranteed. ##
###########################################################

# @ NODE_SCOPE (line: 1, location: (1,0)-(1,8))
# +- nd_tbl: (empty)
# +- nd_args:
# |   (null node)
# +- nd_body:
#     @ NODE_BLOCK (line: 1, location: (1,0)-(1,8))
#     +- nd_head (1):
#     |   @ NODE_METHREF (line: 1, location: (1,0)-(1,6))*
#     |   +- nd_recv:
#     |   |   @ NODE_NIL (line: 1, location: (1,0)-(1,3))
#     |   +- nd_mid: :|
#     +- nd_head (2):
#         @ NODE_LIT (line: 1, location: (1,7)-(1,8))*
#         +- nd_lit: 1

However, it is not compiled correctly, missing putnil:

$ ruby --dump=insns -e 'nil.:|;1'
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,8)> (catch: FALSE)
0000 methodref                    :|                                  (   1)[Li]
0002 putobject_INT2FIX_1_
0003 leave

Compare to:

$ ruby --dump=insns -e 'nil.:|'
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,6)> (catch: FALSE)
0000 putnil                                                           (   1)[Li]
0001 methodref                    :|
0003 leave

This explains a NameError I received before a segfault (and sometimes without a segfault) in the following code:

begin
nil.:|;nil.:|;1
rescue
  p $!
end
#<NameError: undefined method `|' for class `Method'>

Disassembly for that is:

$ ruby --dump=insns -e 'nil.:|;nil.:|;1'   
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,15)> (catch: FALSE)
0000 methodref                    :|                                  (   1)[Li]
0002 methodref                    :|
0004 putobject_INT2FIX_1_
0005 leave

Updated by jeremyevans0 (Jeremy Evans) almost 5 years ago

I think the attached patch should fix it. Passes make check. This is my first time working on the compiler though, so a more experienced committer should probably check the patch.

With the patch:

$ ruby --dump=insns -e 'nil.:|;1'                                                                                          
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,8)> (catch: FALSE)
0000 putnil                                                           (   1)[Li]
0001 methodref                    :|
0003 pop
0004 putobject_INT2FIX_1_
0005 leave
Actions #6

Updated by jeremyevans (Jeremy Evans) almost 5 years ago

  • Status changed from Open to Closed

Applied in changeset git|f296c260ef3b2d1a9299dbb4a84df567972453f2.


Fix segfault when using method reference operator without using result

Fixes [Bug #15985]

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0