Project

General

Profile

Backport #4339 » REPRO4.rb

Reproduces the segfault - rhythmx (Sean Bradly), 01/29/2011 09:09 AM

 
#!/usr/bin/env ruby

require 'thread'
require 'socket'

# Conditions that seem to have to be satisfied:
#
# 1) A call to Marshal.load must be interrupted by a context switch (here a blocking read is used to force it)
# 2) That call needs to be guarded by a Mutex, but it does *not* require another thread to also be using or blocking on the same mutex.
# 3) Another thread calls GC.start manually
# 4) The object being marshaled needs to have at least some child objects

Thread.abort_on_exception = true

threads = []
rcv,snd = IO.pipe

threads << Thread.new do
obj = ('a'..'z').inject({}){|h,s|h[s.intern]=s*1024;h}
data = Marshal.dump(obj)
snd.write(data[0,data.size/2])
sleep(1)
snd.write(data[(data.size/2)..-1])
end

threads << Thread.new do
lock = Mutex.new
lock.synchronize do
Marshal.load(rcv)
end
end

threads << Thread.new do
100.times do
GC.start
end
end

threads.map{|t| t.join}
(1-1/3)