What might cause ruby to lock up while exiting?
Question
I have a ruby script that does a few perforce operations (through the scripting API) then simply ends:
def foo()
...
end
def bar()
...
end
foo()
bar()
puts __LINE__
exit 0
#end of file
...and while the LINE will print out, the process never ends, whether the exit(0) is there or not. This is ruby 1.8.6, primarily on the mac, but I'm seeing this on the PC as well.
I'm doing the usual google poking around, but hoped there might be a voice of experience here to bank on. Thanks.
Solution
I'm not at all familiar with perforce, but the culprit might be an at_exit
method that's stuck in a loop for some reason. Observe the behavior using irb
, for instance:
$ irb
irb(main):001:0> require 'time'
=> true
irb(main):002:0> at_exit { puts Time.now; sleep 10; puts Time.now }
=> #<Proc:0xb7656f64@(irb):2>
irb(main):003:0> exit
Fri Mar 12 19:46:25 -0500 2010
Fri Mar 12 19:46:35 -0500 2010
To confirm whether an at_exit
function is causing the process to hang, you can try hooking into at_exit
. Note that the #{caller}
will display the stack trace of who called at_exit
:
def at_exit &block
@at_exit_counter ||= 0
puts "at_exit #{@at_exit_counter} called"
s = "Calling at_exit ##{@at_exit_counter} from #{caller}"
super { puts s; block.call() }
@at_exit_counter += 1
end
at_exit { puts "I'll never return"; sleep 1 while true; }
at_exit { puts 'I am about to leave.' }
def do_cleanup
puts "Cleaning..."
at_exit { puts 'Cleaning up before exit...' }
end
do_cleanup
which outputs:
at_exit 0 called at_exit 1 called Cleaning... at_exit 2 called Calling at_exit #2 from exitcheck.rb:14:in `do_cleanup'exitcheck.rb:18 Cleaning up before exit... Calling at_exit #1 from exitcheck.rb:10 I am about to leave. Calling at_exit #0 from exitcheck.rb:9 I'll never return
and never returns.