Project

General

Profile

Actions

Bug #4346

closed

Sort_by! causes uniq! to crash on array of hashes

Added by squarism (Chris Dillon) almost 14 years ago. Updated over 13 years ago.

Status:
Closed
Assignee:
-
Target version:
ruby -v:
ruby 1.9.2p136 (2010-12-25 revision 30365) [x86_64-darwin10.5.0]
Backport:
[ruby-core:34997]

Description

=begin
Summary:
Sorting an array of hashes before doing a uniq! causes ruby to crash on uniq!.

Program to reproduce:
a = [
{ :color => "blue", :name => "water" },
{ :color => "red", :name => "fire" },
{ :color => "white", :name => "wind" },
{ :color => "green", :name => "earth" },
{ :color => "green", :name => "moss" },
{ :color => "white", :name => "snow" }
]

a.sort_by! { |e| e[:color] }
a.uniq! {|e| e[:color]}
puts a

A workaround is to do the uniq without the bang. Does not crash.
a = a.uniq {|e| e[:color]}

Changing the uniq! line as above will not crash and produce the expected result:
{:color=>"blue", :name=>"water"}
{:color=>"green", :name=>"moss"}
{:color=>"red", :name=>"fire"}
{:color=>"white", :name=>"wind"}

Taking out the sort_by! line also fixes the crashing.

Crash Happens on Ruby versions:
ruby 1.9.2p136 (2010-12-25 revision 30365) [x86_64-darwin10.5.0]
ruby 1.9.2p174 (2011-01-28 revision 30696) [x86_64-darwin10.6.0]
ruby 1.9.2p136 (2010-12-25 revision 30365) [x86_64-linux]

The method sort_by! is not available in 1.8.7. I did not test with any version of 1.8.7.

GDB on Mac yields:
(gdb) run
Starting program: /Users/user/.rvm/rubies/ruby-1.9.2-head/bin/ruby bug.rb
Reading symbols for shared libraries +++... done
Reading symbols for shared libraries . done
Reading symbols for shared libraries . done

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x000000000000001c
rb_ary_decrement_share [inlined] () at /Users/user/.rvm/src/ruby-1.9.2-head/array.c:195
195 long num = ARY_SHARED_NUM(shared) - 1;
(gdb) bt
#0 rb_ary_decrement_share [inlined] () at /Users/user/.rvm/src/ruby-1.9.2-head/array.c:195
#1 0x000000010000cc99 in rb_ary_modify (ary=4303797720) at array.c:260
#2 0x00000001000128fe in rb_ary_push [inlined] () at /Users/user/.rvm/src/ruby-1.9.2-head/array.c:721
#3 0x00000001000128fe in push_value (key=<value temporarily unavailable, due to optimizations>, val=4303798360, ary=4303797720) at array.c:260
#4 0x0000000100108990 in st_foreach (table=0x1003bb920, func=0x1000128e0 <push_value>, arg=4303797720) at st.c:778
#5 0x0000000100013573 in rb_ary_uniq_bang (ary=4303797720) at array.c:3435
#6 0x000000010017bc13 in vm_call_cfunc [inlined] () at /Users/user/.rvm/src/ruby-1.9.2-head/vm_insnhelper.c:402
#7 0x000000010017bc13 in vm_call_method (th=0x1003016b0, cfp=0x1004ffef8, num=0, blockptr=0x1004fff21, flag=0, id=<value temporarily unavailable, due to optimizations>, me=0x10033f350, recv=4303797720) at vm_insnhelper.c:260
#8 0x0000000100167dc4 in vm_exec_core (th=0x1003016b0, initial=<value temporarily unavailable, due to optimizations>) at insns.def:1006
#9 0x000000010016fa63 in vm_exec (th=0x1003016b0) at vm.c:1147
#10 0x000000010016fd6b in rb_iseq_eval_main (iseqval=4303800760) at vm.c:1388
#11 0x000000010003f4e2 in ruby_exec_internal (n=0x10086c9b8) at eval.c:214
#12 0x0000000100041e6c in ruby_exec_node [inlined] () at /Users/user/.rvm/src/ruby-1.9.2-head/eval.c:261
#13 0x0000000100041e6c in ruby_run_node (n=<value temporarily unavailable, due to optimizations>) at eval.c:260
#14 0x0000000100000ecf in main (argc=2, argv=0x7fff5fbff368) at main.c:35

GDB on Linux yields:

(gdb) run
Starting program: /home/user/.rvm/rubies/ruby-1.9.2-p136/bin/ruby bug.rb
[Thread debugging using libthread_db enabled]
[New Thread 0x7ffff67b5700 (LWP 1423)]

Program received signal SIGSEGV, Segmentation fault.
rb_ary_decrement_share (ary=6517200) at array.c:195
195 long num = ARY_SHARED_NUM(shared) - 1;
(gdb) bt
#0 rb_ary_decrement_share (ary=6517200) at array.c:195
#1 rb_ary_modify (ary=6517200) at array.c:260
#2 0x00007ffff79f90a3 in rb_ary_push (ary=6517216, item=7746848) at array.c:721
#3 0x00007ffff79f97ec in push_value (key=, val=7746848, ary=0) at array.c:3399
#4 0x00007ffff7ad4962 in st_foreach (table=0x7634e0, func=0x7ffff79f97e0 <push_value>, arg=6517200) at st.c:778
#5 0x00007ffff79fdb0c in rb_ary_uniq_bang (ary=6517200) at array.c:3435
#6 0x00007ffff7b35590 in vm_call_cfunc (th=0x603ce0, cfp=0x7ffff68b5f08, num=0, blockptr=, flag=, id=6517336,
me=0x6bd020, recv=6517200) at vm_insnhelper.c:402
#7 vm_call_method (th=0x603ce0, cfp=0x7ffff68b5f08, num=0, blockptr=, flag=, id=6517336, me=0x6bd020,
recv=6517200) at vm_insnhelper.c:524
#8 0x00007ffff7b285e9 in vm_exec_core (th=0x603ce0, initial=) at insns.def:1006
#9 0x00007ffff7b2edba in vm_exec (th=) at vm.c:1147
#10 0x00007ffff7b2f1f0 in rb_iseq_eval_main (iseqval=6520000) at vm.c:1388
#11 0x00007ffff7a278c2 in ruby_exec_internal (n=) at eval.c:214
#12 0x00007ffff7a278ed in ruby_exec_node (n=0x637cc0) at eval.c:261
#13 0x00007ffff7a2936e in ruby_run_node (n=0x637cc0) at eval.c:254
#14 0x000000000040095b in main (argc=2, argv=0x7fffffffe488) at main.c:35

The crash report (all 1.9's give similar output):
/tmp/bug.rb:64: [BUG] Segmentation fault
ruby 1.9.2p136 (2010-12-25 revision 30365) [x86_64-darwin10.5.0]

-- control frame ----------
c:0004 p:---- s:0010 b:0010 l:000009 d:000009 CFUNC :uniq!
c:0003 p:0090 s:0007 b:0007 l:0014e8 d:001a60 EVAL /tmp/bug.rb:64
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH
c:0001 p:0000 s:0002 b:0002 l:0014e8 d:0014e8 TOP

-- Ruby level backtrace information ----------------------------------------
/tmp/bug.rb:64:in <main>' /tmp/bug.rb:64:in uniq!'

-- C level backtrace information -------------------------------------------

[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html
=end

Actions

Also available in: Atom PDF

Like0
Like0Like0