Project

General

Profile

Actions

Bug #16184

closed

Entry persists in catch table even though its labels were removed, which may cause [BUG]

Added by iv-m (Ivan Melnikov) over 4 years ago. Updated over 4 years ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 2.5.5p157 (2019-03-15) [mipsel-linux]
[ruby-core:95105]

Description

When remove_unreachable_chunk removes the code from within a rescue block, the catch table entry corresponding the block is not removed. Here is a simple reproducer (tested with ruby 2.5.5):

puts "BEGIN"

if false
  begin
    require "some_mad_stuff"
  rescue LoadError
    puts "no mad stuff loaded"
  end
end

puts "END"

Here is the corresponding disasm:

== disasm: #<ISeq:<main>@test2.rb:1 (1,0)-(12,10)>======================
== catch table
| catch type: rescue st: 11022376 ed: 11022516 sp: -002 cont: 0000
== disasm: #<ISeq:rescue in <main>@test2.rb:7 (7,2)-(9,2)>==============
local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] "\#$!"
0000 getlocal_OP__WC__0 "\#$!"                                        (   7)
0002 getinlinecache   9, <is:0>
0005 getconstant      :LoadError
0007 setinlinecache   <is:0>
0009 checkmatch       3
0011 branchunless     20
0013 putself                                                          (   8)[Li]
0014 putstring        "no mad stuff loaded"
0016 opt_send_without_block <callinfo!mid:puts, argc:1, FCALL|ARGS_SIMPLE>, <callcache>
0019 leave                                                            (   7)
0020 getlocal_OP__WC__0 "\#$!"
0022 throw            0
| catch type: retry  st: 11022516 ed: 0000 sp: -001 cont: 11022376
|------------------------------------------------------------------------
0000 putself                                                          (   2)[Li]
0001 putstring        "BEGIN"
0003 opt_send_without_block <callinfo!mid:puts, argc:1, FCALL|ARGS_SIMPLE>, <callcache>
0006 pop
0007 putself                                                          (  12)[Li]
0008 putstring        "END"
0010 opt_send_without_block <callinfo!mid:puts, argc:1, FCALL|ARGS_SIMPLE>, <callcache>
0013 leave

The interesting line here is:

catch type: rescue st: 11022376 ed: 11022516 sp: -002 cont: 0000

As the instruction corresponding the begin..rescue block were optimized away, the sp filed of the continue label was still -1 (or -2) and positions of start, end and continue labels are never initialized. When any exception happens in the remaining code (requires a bit more complex reproducer, happens in real life), this may cause an interpreter to segfault.

I've discovered this issue when building net-scp gem, which has this if false; require pattern in its Rakefile: https://github.com/net-ssh/net-scp/blob/v2.0.0/Rakefile . Interpreter reproducibly segfaults when trying to run it on my MIPS32 LE machine.


Files

ruby-2.5.5-alt-fix-crash-on-mipsel.patch (372 Bytes) ruby-2.5.5-alt-fix-crash-on-mipsel.patch patch that initializes `position` field iv-m (Ivan Melnikov), 09/26/2019 01:19 PM
crush.log (8.14 KB) crush.log [BUG] Segmentation fault at 0x00000000 iv-m (Ivan Melnikov), 09/27/2019 09:06 AM
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0