Benchmark segfault ]

On 11/06/07, Robert K. [email protected] wrote:

Benchmark::bmbm do |x|
two-bang 1604.816667 1.350000 1606.166667 (963.803356)
x.report(“zip”) { Hash[ *id_list.zip(id_list.collect {|e| e.object_id})] }
GC. You’ll probably see much different results if your input array is
much shorter (try with 10 or 100 elements).

I also get a segfault (with 1.8.5 on Gentoo):

ruby -w test.rb
Rehearsal --------------------------------------------
inject 7.210000 0.870000 8.080000 ( 13.011414)
non-bang 4620.790000 179.730000 4800.520000 (6029.976497)
bang 4586.140000 200.530000 4786.670000 (5970.267190)
two-bang 4599.560000 268.080000 4867.640000 (6035.687979)
------------------------------- total: 14462.910000sec

           user     system      total        real

inject 10.740000 1.990000 12.730000 ( 15.500874)
non-bang Segmentation fault
hramrach@hp-tc2110:11(0) 06120053 16]~ $ ruby -v
ruby 1.8.5 (2006-12-04 patchlevel 2) [i686-linux]

Of course, it would be better to test with 1.8.6 but it takes quite
some time to retest :wink:

Thanks

Michal

On 12.06.2007 11:52, Michal S. wrote:

Hash[ *id_list.collect { |e| [e,e.object_id]}.flatten]
id_list = (1…1_000_000).to_a

non-bang Segmentation fault
hramrach@hp-tc2110:11(0) 06120053 16]~ $ ruby -v
ruby 1.8.5 (2006-12-04 patchlevel 2) [i686-linux]

Of course, it would be better to test with 1.8.6 but it takes quite
some time to retest :wink:

Thanks

Michal

I believe it’s the star operator:

13:10:22 [Temp]: ruby -e ‘Hash[*Array.new(ARGV.shift.to_i) ]’ 1000000
13:10:35 [Temp]: ruby -e ‘Hash[*Array.new(ARGV.shift.to_i) ]’ 10000000
-e:1: [BUG] Segmentation fault
ruby 1.8.6 (2007-03-13) [i386-cygwin]

Aborted (core dumped)
13:10:39 [Temp]: ruby -e ‘def f(*a) end; f(*Array.new(ARGV.shift.to_i))’
1000000
13:11:09 [Temp]: ruby -e ‘def f(*a) end; f(*Array.new(ARGV.shift.to_i))’
10000000
-e:1: [BUG] Segmentation fault
ruby 1.8.6 (2007-03-13) [i386-cygwin]

Aborted (core dumped)
13:11:14 [Temp]: uname -a
CYGWIN_NT-5.2-WOW64 PDBXPWSRK38 1.5.24(0.156/4/2) 2007-01-31 10:57 i686
Cygwin
13:11:36 [Temp]: ruby --version
ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-cygwin]

Kind regards

robert

On 12.06.2007 16:16, Florian F. wrote:

1000000
ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-cygwin]

The reason for this problem is, that the stack is used to pass A LOT of
arguments to the Hash.[] method. If the stack size of the executed process isn’t
big enough (check your resource limits), this can lead to crashes.

That was what I was guessing. However, I haven’t enough insight to
verify. There is at least one point that causes me doubt: the array can
be handled and stored like any other array, so it should be on the heap
(or it is implicitly moved there).

Kind regards

robert

On Tue, Jun 12, 2007 at 11:25:04PM +0900, Robert K. wrote:

On 12.06.2007 16:16, Florian F. wrote:

Robert K. wrote:

I believe it’s the star operator:

13:10:22 [Temp]: ruby -e ‘Hash[*Array.new(ARGV.shift.to_i) ]’ 1000000
13:10:35 [Temp]: ruby -e ‘Hash[*Array.new(ARGV.shift.to_i) ]’ 10000000
-e:1: [BUG] Segmentation fault
ruby 1.8.6 (2007-03-13) [i386-cygwin]
[…]

The reason for this problem is, that the stack is used to pass A LOT of
arguments to the Hash.[] method. If the stack size of the executed process
isn’t
big enough (check your resource limits), this can lead to crashes.

That was what I was guessing. However, I haven’t enough insight to
verify. There is at least one point that causes me doubt: the array can
be handled and stored like any other array, so it should be on the heap
(or it is implicitly moved there).

$ ruby -e ‘Hash[*Array.new(ARGV.shift.to_i) ]’ 2091000
-e:1:in []': stack level too deep (SystemStackError) from -e:1 $ ruby -e 'Hash[*Array.new(ARGV.shift.to_i) ]' 2092000 Segmentation fault $ ulimit -s 8192 $ ulimit -s 16384 $ ruby -e 'Hash[*Array.new(ARGV.shift.to_i) ]' 2092000 $ ruby -e 'Hash[*Array.new(ARGV.shift.to_i) ]' 4184000 -e:1:in[]’: stack level too deep (SystemStackError)
from -e:1
$ ruby -e ‘Hash[*Array.new(ARGV.shift.to_i) ]’ 4190000
Segmentation fault

Robert K. wrote:

13:11:09 [Temp]: ruby -e ‘def f(*a) end; f(*Array.new(ARGV.shift.to_i))’
10000000
-e:1: [BUG] Segmentation fault
ruby 1.8.6 (2007-03-13) [i386-cygwin]

Aborted (core dumped)
13:11:14 [Temp]: uname -a
CYGWIN_NT-5.2-WOW64 PDBXPWSRK38 1.5.24(0.156/4/2) 2007-01-31 10:57 i686
Cygwin
13:11:36 [Temp]: ruby --version
ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-cygwin]

The reason for this problem is, that the stack is used to pass A LOT of
arguments to the Hash.[] method. If the stack size of the executed
process isn’t
big enough (check your resource limits), this can lead to crashes.

Hi,

At Wed, 13 Jun 2007 00:50:30 +0900,
Florian F. wrote in [ruby-talk:255348]:

Yes, the implementation of this is in eval.c’s rb_call0, after that the
arguments are passed along via the argc/argv function arguments. Ruby also tries
to throw a SystemStackError in rb_call0 like Mauricio has shown, but this isn’t
guaranteed to work in all cases.

Actually, the definition of TMP_ALLOC. Try replacing #ifdef
C_ALLOCA with #if 1.

Robert K. wrote:

That was what I was guessing. However, I haven’t enough insight to
verify. There is at least one point that causes me doubt: the array can
be handled and stored like any other array, so it should be on the heap
(or it is implicitly moved there).

Yes, the implementation of this is in eval.c’s rb_call0, after that the
arguments are passed along via the argc/argv function arguments. Ruby
also tries
to throw a SystemStackError in rb_call0 like Mauricio has shown, but
this isn’t
guaranteed to work in all cases.