# SystemStackError: stack level too deep

**URL:** <https://www.ruby-forum.com/t/systemstackerror-stack-level-too-deep/130621>\
**Category:** Ruby\
**Created:** [February 29, 2008, 10:16pm UTC](https://www.ruby-forum.com/t/systemstackerror-stack-level-too-deep/130621 "2008-02-29T22:16:01Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![oliver-peng](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/b3f665/32.png) [@oliver-peng](https://www.ruby-forum.com/u/oliver-peng)\
**Post date:** [February 29, 2008, 10:16pm UTC](https://www.ruby-forum.com/t/systemstackerror-stack-level-too-deep/130621/1 "2008-02-29T22:16:01Z")

</div>

Now I am writing a server code to handle each connection by forking a  
new process. Here is the code:

@tcpServer = TCPServer.new(host, port)

while true  
if tcp = @tcpServer.accept  
fork do  
// handle all request in this connection  
end  
tcp && tcp.close  
end  
end

@tcpServer.close\_read  
@tcpServer.close\_write

I also set up trap to handle CLD signal:  
trap(“CLD”) {  
pid\_info\_array = Process.waitall  
}

After a period of time, I got the error:

SystemStackError: stack level too deep

The position is at the line of Process.waitall.

I have tried to use Process.wait, but this problem still exist.

Any ideas. Thanks.

---

<div class="post-metadata">

**Author:** ![oliver-peng](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/b3f665/32.png) [@oliver-peng](https://www.ruby-forum.com/u/oliver-peng)\
**Post date:** [March 1, 2008, 6:10pm UTC](https://www.ruby-forum.com/t/systemstackerror-stack-level-too-deep/130621/2 "2008-03-01T18:10:55Z")

</div>

On 29.02.2008 22:15, Oliver P. wrote:

> ```
> tcp && tcp.close
> 
> ```
> 
> After a period of time, I got the error:
> 
> SystemStackError: stack level too deep
> 
> The position is at the line of Process.waitall.
> 
> I have tried to use Process.wait, but this problem still exist.
> 
> Any ideas. Thanks.

You are doing an unhealthy mix: Process.waitall and wait block to wait  
for an event but SIGCLD is supposed to be called when that event  
happens.

So either, use Process.waitall in main or change the trap code to do  
something like manipulating a child process counter so you can detect  
when the last is gone.

But at the heart of your problem is a logic error: you cannot have an  
endless loop and wait for all children to exit at the same time. Either  
you decide in the main loop that now no more children are to be created  
OR you just have a main loop that runs forever - but then there is no  
point in waiting for all childs to terminate.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![oliver-peng](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/b3f665/32.png) [@oliver-peng](https://www.ruby-forum.com/u/oliver-peng)\
**Post date:** [March 3, 2008, 8:25pm UTC](https://www.ruby-forum.com/t/systemstackerror-stack-level-too-deep/130621/3 "2008-03-03T20:25:43Z")

</div>

Robert K. wrote:

> On 29.02.2008 22:15, Oliver P. wrote:
> 
> > ```
> > tcp && tcp.close
> > 
> > ```
> > 
> > After a period of time, I got the error:
> > 
> > SystemStackError: stack level too deep
> > 
> > The position is at the line of Process.waitall.
> > 
> > I have tried to use Process.wait, but this problem still exist.
> > 
> > Any ideas. Thanks.
> 
> But at the heart of your problem is a logic error: you cannot have an  
> endless loop and wait for all children to exit at the same time. Either  
> you decide in the main loop that now no more children are to be created  
> OR you just have a main loop that runs forever - but then there is no  
> point in waiting for all childs to terminate.
> 
> Kind regards
> 
> robert  
> Hi Robert:

Thanks for your replay.

> You are doing an unhealthy mix: Process.waitall and wait block to wait  
> for an event but SIGCLD is supposed to be called when that event  
> happens.
> 
> So either, use Process.waitall in main or change the trap code to do  
> something like manipulating a child process counter so you can detect  
> when the last is gone.

Sorry. I am not sure what do you mean. In my code, it trap the CLD  
signal to run wait method to clean the zombie sub-process, which is same  
as the sample code in book ‘Programming ruby’.

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?

Thanks.

---

<div class="post-metadata">

**Author:** ![oliver-peng](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/b3f665/32.png) [@oliver-peng](https://www.ruby-forum.com/u/oliver-peng)\
**Post date:** [March 3, 2008, 9:27pm UTC](https://www.ruby-forum.com/t/systemstackerror-stack-level-too-deep/130621/4 "2008-03-03T21:27:16Z")

</div>

2008/3/3, Oliver P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Robert K. 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

---

<div class="post-metadata">

**Author:** ![oliver-peng](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/b3f665/32.png) [@oliver-peng](https://www.ruby-forum.com/u/oliver-peng)\
**Post date:** [March 3, 2008, 9:54pm UTC](https://www.ruby-forum.com/t/systemstackerror-stack-level-too-deep/130621/5 "2008-03-03T21:54:18Z")

</div>

Robert K. wrote:

> 2008/3/3, Oliver P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):
> 
> > Robert K. 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?

Thanks.

---

<div class="post-metadata">

**Author:** ![oliver-peng](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/b3f665/32.png) [@oliver-peng](https://www.ruby-forum.com/u/oliver-peng)\
**Post date:** [March 5, 2008, 6:45pm UTC](https://www.ruby-forum.com/t/systemstackerror-stack-level-too-deep/130621/6 "2008-03-05T18:45:35Z")

</div>

On 03.03.2008 21:54, Oliver P. wrote:

> > > 
> > 
> > 5.times do |i|
> > 
> > pp Process.waitall  
> > try to use waitall later. So I still don’t know why the SystemStackError  
> > puts “pid #{pid} exited”  
> > fork do  
> > end  
> > require ‘socket’  
> > 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
