Ruby Segfault: Marshaling large objects

Hi All –

I’m trying to marshal large objects. 10Mb objects (ish) cause Ruby to
crash (segfault) on Marshal.load. The following example reliably
reproduces the problem on my machine:

s = '%10000000d' % 1; nil # Create 10Mb string
d = Marshal.dump(s); nil # Dump it
t = Marshal.load(d); nil # Load it -- causes segfault

The trailing '; nil’s are to stop irb echoing the 10Mb strings (it
takes a while :-).

Ruby and OS versions:

[twp20@spark twp20]$ ruby --version
ruby 1.6.7 (2002-03-01) [i686-linux]
[twp20@spark twp20]$ uname -a
Linux spark.clare.cam.ac.uk 2.4.19 #5 Fri Aug 23 10:44:37 BST 2002 i686
unknown

More info available on request. Please replace ‘spam’ with ‘cam’ in my
email address if you want to email me directly.

Any pointers on how to fix this bug? Is it known and/or fixed in a more
recent release?

Cheers,

Tom

I was able to duplicate this in both 1.6.7 and 1.7.2, and in CVS.
Here’s a backtrace of the CVS version crashing:

···

Hi All –

I’m trying to marshal large objects. 10Mb objects (ish) cause Ruby to
crash (segfault) on Marshal.load. The following example reliably
reproduces the problem on my machine:

s = ‘%10000000d’ % 1; nil # Create 10Mb string
d = Marshal.dump(s); nil # Dump it
t = Marshal.load(d); nil # Load it – causes segfault


pabs@picard:~/proj/marshaltest> cat ./marshaltest.rb
#!/usr/bin/ruby

s = ‘%10d’ % 1; # Create Smaller string
d = Marshal.dump(s); # Dump it
t = Marshal.load(d); # Load it
puts ‘okay’

s = ‘%10000000d’ % 1; # Create 10Mb string
d = Marshal.dump(s); # Dump it
t = Marshal.load(d); # Load it – causes segfault

pabs@picard:~/proj/marshaltest> gdb ~/cvs/ruby/ruby
Starting program: /home/pabs/cvs/ruby/ruby ./marshaltest.rb
okay

Program received signal SIGSEGV, Segmentation fault.
0x08076632 in r_string (arg=0xbfffede0) at marshal.c:789
789 r_bytes2(buf, len, arg);
(gdb) bt
#0 0x08076632 in r_string (arg=0xbfffede0) at marshal.c:789
#1 0x08076c10 in r_object0 (arg=0xbfffede0, proc=0) at marshal.c:942
#2 0x080773a5 in r_object (arg=0xbfffede0) at marshal.c:1131
#3 0x080773b9 in load (arg=0xbfffede0) at marshal.c:1138
#4 0x08059d60 in rb_ensure (b_proc=0x80773a8 , data1=3221220832,
e_proc=0x80773bc <load_ensure>, data2=3221220832) at eval.c:4237
#5 0x080775d4 in marshal_load (argc=1, argv=0xbfffeff4) at marshal.c:1197
#6 0x0805a488 in call_cfunc (func=0x80773d4 <marshal_load>, recv=1075542968,
len=-1, argc=1, argv=0xbfffeff4) at eval.c:4417
#7 0x0805a9a2 in rb_call0 (klass=1075542908, recv=1075542968, id=8937,
oid=8937, argc=1, argv=0xbfffeff4, body=0x401b7b18, nosuper=1)
at eval.c:4550
#8 0x0805b176 in rb_call (klass=1075542908, recv=1075542968, mid=8937,
argc=1, argv=0xbfffeff4, scope=0) at eval.c:4766
#9 0x080563df in rb_eval (self=1075599988, n=0x401b74ec) at eval.c:2757
#10 0x08056f2a in rb_eval (self=1075599988, n=0x401b780c) at eval.c:2930
#11 0x08052678 in eval_node (self=1075599988, node=0x401b780c) at eval.c:1125
#12 0x08052aa6 in ruby_run () at eval.c:1270
#13 0x08051196 in main (argc=2, argv=0xbffffb04, envp=0xbffffb10) at main.c:50
(gdb) p buf
$1 = 0xbf675578 <Address 0xbf675578 out of bounds>
(gdb) p len
$2 = 10000000
(gdb) p arg
$3 = (struct load_arg *) 0xbfffede0

pabs@picard:~/cvs/ruby> ruby -v && ruby1.7 -v && ~/cvs/ruby/ruby -v &&
uname -a
ruby 1.6.7 (2002-03-19) [i386-linux]
ruby 1.7.2 (2002-07-13) [i386-linux]
ruby 1.7.3 (2002-09-03) [i686-linux]
Linux picard 2.4.19-rc3-preempt #9 SMP Sat Aug 3 00:47:22 EDT 2002 i686
unknown unknown GNU/Linux

I perused the source but didn’t see anything really obvious. I’ll take
a better look after lunch.

The trailing '; nil’s are to stop irb echoing the 10Mb strings (it
takes a while :-).

Ruby and OS versions:

[twp20@spark twp20]$ ruby --version
ruby 1.6.7 (2002-03-01) [i686-linux]
[twp20@spark twp20]$ uname -a
Linux spark.clare.cam.ac.uk 2.4.19 #5 Fri Aug 23 10:44:37 BST 2002 i686
unknown

More info available on request. Please replace ‘spam’ with ‘cam’ in my
email address if you want to email me directly.

Any pointers on how to fix this bug? Is it known and/or fixed in a more
recent release?

Cheers,

Tom


Paul Duncan pabs@pablotron.org pabs in #gah (OPN IRC)
http://www.pablotron.org/ OpenPGP Key ID: 0x82C29562

Here's a backtrace of the CVS version crashing:

it segfault on alloca()

Guy Decoux

(…)

pabs@picard:~/proj/marshaltest> cat ./marshaltest.rb
#!/usr/bin/ruby

s = ‘%10d’ % 1; # Create Smaller string
d = Marshal.dump(s); # Dump it
t = Marshal.load(d); # Load it
puts ‘okay’

s = ‘%10000000d’ % 1; # Create 10Mb string
d = Marshal.dump(s); # Dump it
t = Marshal.load(d); # Load it – causes segfault

pabs@picard:~/proj/marshaltest> gdb ~/cvs/ruby/ruby
Starting program: /home/pabs/cvs/ruby/ruby ./marshaltest.rb
okay

Program received signal SIGSEGV, Segmentation fault.
(…)

I perused the source but didn’t see anything really obvious. I’ll take
a better look after lunch.

The sources is ok (i think). No problems to run on Windows ME 64Mb.

ruby 1.6.7 (2002-03-01) [i586-mswin32] (from Pragmatic Programmer’s)
and
ruby 1.7.3 (2002-09-02) [i386-cygwin] (from CVS)

's
Guaracy

···

----- Original Message -----
From: “Paul Duncan” pabs@pablotron.org

HP: www.guaracy.cjb.net

Here’s a backtrace of the CVS version crashing:

it segfault on alloca()

Seems to be that way, yeah.

···

Guy Decoux


Paul Duncan pabs@pablotron.org pabs in #gah (OPN IRC)
http://www.pablotron.org/ OpenPGP Key ID: 0x82C29562

Hi,

“Guaracy Monteiro” guaracybm@ig.com.br writes:

···

----- Original Message -----
From: “Paul Duncan” pabs@pablotron.org

(…)

pabs@picard:~/proj/marshaltest> cat ./marshaltest.rb
#!/usr/bin/ruby

s = ‘%10d’ % 1; # Create Smaller string
d = Marshal.dump(s); # Dump it
t = Marshal.load(d); # Load it
puts ‘okay’

s = ‘%10000000d’ % 1; # Create 10Mb string
d = Marshal.dump(s); # Dump it
t = Marshal.load(d); # Load it – causes segfault

pabs@picard:~/proj/marshaltest> gdb ~/cvs/ruby/ruby
Starting program: /home/pabs/cvs/ruby/ruby ./marshaltest.rb
okay

Program received signal SIGSEGV, Segmentation fault.
(…)

I perused the source but didn’t see anything really obvious. I’ll take
a better look after lunch.

The sources is ok (i think). No problems to run on Windows ME 64Mb.

ruby 1.6.7 (2002-03-01) [i586-mswin32] (from Pragmatic Programmer’s)
and
ruby 1.7.3 (2002-09-02) [i386-cygwin] (from CVS)

That’s because the stack of mswin32/mingw32/cygwin ruby has
reserved 32MB.

% objdump -p =ruby.exe |grep -i stack
SizeOfStackReserve 02000000
SizeOfStackCommit 00001000


eban