Issue #16184 has been updated by iv-m (Ivan Melnikov). File ruby-2.5.5-alt-fix-crash-on-mipsel.patch added Of course, while having some strange cache table entries would be pretty ok if they were not used (like it usually happens on x86_64). To make sure they are never used compiler should initialize the `position` field of the labels. I'm attaching a patch that does just that -- at least this makes segfaults irreproducible. ---------------------------------------- Bug #16184: Entry persists in catch table even though its labels were removed, which may cause [BUG] https://bugs.ruby-lang.org/issues/16184#change-81740 * Author: iv-m (Ivan Melnikov) * Status: Open * Priority: Normal * Assignee: * Target version: * ruby -v: ruby 2.5.5p157 (2019-03-15) [mipsel-linux] * Backport: 2.5: UNKNOWN, 2.6: UNKNOWN ---------------------------------------- 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): ``` ruby 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 `position`s 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) -- https://bugs.ruby-lang.org/ Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe> <http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>