From: Robert Klemme Date: 2008-03-06T02:44:55+09:00 Subject: Re: SystemStackError: stack level too deep On 03.03.2008 21:54, Oliver Peng wrote: > Robert Klemme wrote: >> 2008/3/3, Oliver Peng : >>> Robert Klemme wrote: >>> as the sample code in book 'Programming ruby'. >> There is no trace of Process.waitall in the signal handler sample code. >> >>> When a child process dies, a signal, SIGCHLD (or SIGCLD) is sent to its >>> parent process. So when I run Process.wait, I always should get the >>> response at once. And this code can work. The only problem is sometimes >>> SystemStackError was raised. >>> >>> Can you please use sample code to show me where is the problem? >> The problem is in waitall. The sample code otherwise works ok. Try >> this >> >> trap "CLD" do >> puts "#{Process.wait} exited" >> # alternative >> p Process.wait2 >> end >> >> 5.times do |i| >> pid = fork do >> puts "proc #{i}" >> end and puts "#{pid} created" >> end >> >> puts "all children created" >> >> sleep 10 >> >> Here's another approach >> >> require 'pp' >> >> 5.times do |i| >> pid = fork do >> puts "proc #{i}" >> end and puts "#{pid} created" >> end >> >> puts "all children created" >> >> pp Process.waitall >> >> >> Kind regards >> >> robert > > Ok. I see. You mean that waitall shouldn't be used in trap 'CLD' because > it would wait until all process exit. > > But I use wait at first and get the SystemStackError exception. Then I > try to use waitall later. So I still don't know why the SystemStackError > exception is raised. > > I also try to write test code and please have a look: > > ---------------------------------------------------- > Server code: > require 'socket' > > trap('CLD') do > pid = Process.wait > puts "pid #{pid} exited" > end > > class TestServer > > def initialize > @tcpServer = TCPServer.new('0.0.0.0', 7777) > end > > def run > while tcp = @tcpServer.accept > fork do > begin > while str = tcp.gets() > tcp.puts("hello") > end > ensure > tcp.close_read > tcp.close_write > end > end > tcp.close > end > end > end > > server = TestServer.new > > server.run > > ------------------------------------------------ > Client code: > > require 'socket' > > threads = [] > 100.times do > threads << Thread.new() do > while true > socket = TCPSocket.new('localhost', 7777) > socket.puts("hello") > sleep 1 > socket.gets > socket.close > sleep 10 > end > end > end > > threads.each {|thr| thr.join} > > From the server output, I can see that CLD signal has been traped and > server puts the process exit. But from top I can see that zombie process > are getting more and more. Is there some problem in the code logic? I can't really see one. Can you post the exception with the stack trace? Kind regards robert