Closed ioquatix closed 9 years ago
@tarcieri I'm pretty sure this is faulty without ensure since heaps of exceptions will get thrown back out, but I'm not sure if that's the correct behaviour or not. When I print out exceptions, I see the following before the segfault:
From the code:
monitor = @selector.register(io, set)
monitor.value = Task.current
Task.suspend :iowait
ensure
puts "Exception: #{$!}"
monitor.close
end
I get:
Exception: task was terminated
/Users/samuel/.rvm/gems/ruby-2.0.0-p576/gems/celluloid-io-0.16.1/lib/celluloid/io/reactor.rb:47: [BUG] Segmentation fault
ruby 2.0.0p576 (2014-09-19 revision 47628) [x86_64-darwin14.0.0]
-- Crash Report log information --------------------------------------------
See Crash Report log file under the one of following:
* ~/Library/Logs/CrashReporter
* /Library/Logs/CrashReporter
* ~/Library/Logs/DiagnosticReports
* /Library/Logs/DiagnosticReports
the more detail of.
-- Control frame information -----------------------------------------------
c:0018 p:---- s:0060 e:000059 CFUNC :close
c:0017 p:0019 s:0057 e:000056 RESCUE /Users/samuel/.rvm/gems/ruby-2.0.0-p576/gems/celluloid-io-0.16.1/lib/celluloid/io/reactor.rb:47
c:0016 p:0193 s:0054 e:000052 METHOD /Users/samuel/.rvm/gems/ruby-2.0.0-p576/gems/celluloid-io-0.16.1/lib/celluloid/io/reactor.rb:47
c:0015 p:0011 s:0047 e:000046 METHOD /Users/samuel/.rvm/gems/ruby-2.0.0-p576/gems/celluloid-io-0.16.1/lib/celluloid/io/reactor.rb:21
c:0014 p:0050 s:0043 e:000042 METHOD /Users/samuel/.rvm/gems/ruby-2.0.0-p576/gems/celluloid-io-0.16.1/lib/celluloid/io.rb:53
c:0013 p:0018 s:0038 e:000037 METHOD /Users/samuel/.rvm/gems/ruby-2.0.0-p576/gems/celluloid-io-0.16.1/lib/celluloid/io/tcp_server.rb:19
c:0012 p:0012 s:0035 e:000033 BLOCK /Users/samuel/Documents/Programming/Internet/rubydns/lib/rubydns/handler.rb:150 [FINISH]
c:0011 p:---- s:0032 e:000031 CFUNC :loop
c:0010 p:0007 s:0029 e:000028 METHOD /Users/samuel/Documents/Programming/Internet/rubydns/lib/rubydns/handler.rb:150 [FINISH]
c:0009 p:---- s:0026 e:000025 CFUNC :public_send
c:0008 p:0040 s:0021 e:000020 METHOD /Users/samuel/.rvm/gems/ruby-2.0.0-p576/gems/celluloid-0.16.0/lib/celluloid/calls.rb:26
c:0007 p:0031 s:0016 e:000015 METHOD /Users/samuel/.rvm/gems/ruby-2.0.0-p576/gems/celluloid-0.16.0/lib/celluloid/calls.rb:122
c:0006 p:0011 s:0011 e:000010 BLOCK /Users/samuel/.rvm/gems/ruby-2.0.0-p576/gems/celluloid-0.16.0/lib/celluloid/cell.rb:60
c:0005 p:0041 s:0009 e:000008 BLOCK /Users/samuel/.rvm/gems/ruby-2.0.0-p576/gems/celluloid-0.16.0/lib/celluloid/cell.rb:71
c:0004 p:0026 s:0007 e:000006 BLOCK /Users/samuel/.rvm/gems/ruby-2.0.0-p576/gems/celluloid-0.16.0/lib/celluloid/actor.rb:357
c:0003 p:0073 s:0005 e:000004 BLOCK /Users/samuel/.rvm/gems/ruby-2.0.0-p576/gems/celluloid-0.16.0/lib/celluloid/tasks.rb:57
c:0002 p:0060 s:0003 e:000002 BLOCK /Users/samuel/.rvm/gems/ruby-2.0.0-p576/gems/celluloid-0.16.0/lib/celluloid/tasks/task_fiber.rb:15 [FINISH]
c:0001 p:---- s:0001 e:000000 ------
I'm wondering if this is because "task was exited" means that the reactor has already been shut down and the monitor is no longer valid?
This looks like a bug in the C extension of nio4r
@tarcieri Are you able to check nio4r and find out what is going on?
I can take a look tonight. Knowing the ordering of events or a simple repro of the crash would be helpful
RubyDNS has a spec which reproduces the crash systematically on Ruby 2.0.0 but not other versions.
https://github.com/ioquatix/rubydns/blob/master/spec/rubydns/celluloid_bug_spec.rb
@tarcieri Here is the requested PR. https://github.com/celluloid/celluloid-io/issues/121
@TiagoCardoso1983 are you able to test too?
I was considering that it would be nice if there was a better way of catching the TerminatedError
. It sort of seems.. ugly..
@tarcieri I've added a spec which fails before the patch and passes afterwards, it's based on @TiagoCardoso1983's example, but it's structured using a module which you didn't like in the past, please feel free to modify to suit whatever structure you like.
I've run RubyDNS tests against this PR and they are all passing too which is a good sign since RubyDNS IMHO pushes Celluloid pretty hard.
Odd transient failing case on Travis: https://travis-ci.org/celluloid/celluloid-io/jobs/43071935
1) Celluloid::IO behaves like a Celluloid Actor using Threads timers schedules recurring timers which fire in the future
Failure/Error: actor.fired.should be 3
fatal:
No live threads left. Deadlock?
Shared Example Group: "a Celluloid Actor" called from ./spec/celluloid/io/actor_spec.rb:4
# /home/travis/.rvm/rubies/ruby-2.0.0-p594/lib/ruby/2.0.0/thread.rb:72:in `sleep'
# /home/travis/.rvm/rubies/ruby-2.0.0-p594/lib/ruby/2.0.0/thread.rb:72:in `block (2 levels) in wait'
# /home/travis/.rvm/rubies/ruby-2.0.0-p594/lib/ruby/2.0.0/thread.rb:68:in `handle_interrupt'
# /home/travis/.rvm/rubies/ruby-2.0.0-p594/lib/ruby/2.0.0/thread.rb:68:in `block in wait'
# /home/travis/.rvm/rubies/ruby-2.0.0-p594/lib/ruby/2.0.0/thread.rb:66:in `handle_interrupt'
# /home/travis/.rvm/rubies/ruby-2.0.0-p594/lib/ruby/2.0.0/thread.rb:66:in `wait'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/bundler/gems/celluloid-c31d1e9277db/lib/celluloid/mailbox.rb:62:in `block in check'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/timers-4.0.1/lib/timers/wait.rb:14:in `for'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/bundler/gems/celluloid-c31d1e9277db/lib/celluloid/mailbox.rb:57:in `check'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/bundler/gems/celluloid-c31d1e9277db/lib/celluloid/mailbox.rb:75:in `block in receive'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/timers-4.0.1/lib/timers/wait.rb:14:in `for'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/bundler/gems/celluloid-c31d1e9277db/lib/celluloid/mailbox.rb:74:in `receive'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/bundler/gems/celluloid-c31d1e9277db/lib/celluloid/calls.rb:113:in `block in wait'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/bundler/gems/celluloid-c31d1e9277db/lib/celluloid/calls.rb:112:in `loop'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/bundler/gems/celluloid-c31d1e9277db/lib/celluloid/calls.rb:112:in `wait'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/bundler/gems/celluloid-c31d1e9277db/lib/celluloid.rb:117:in `suspend'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/bundler/gems/celluloid-c31d1e9277db/lib/celluloid/calls.rb:104:in `response'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/bundler/gems/celluloid-c31d1e9277db/lib/celluloid/calls.rb:108:in `value'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/bundler/gems/celluloid-c31d1e9277db/lib/celluloid/proxies/sync_proxy.rb:33:in `method_missing'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/bundler/gems/celluloid-c31d1e9277db/lib/celluloid/rspec/actor_examples.rb:857:in `block (3 levels) in <top (required)>'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-2.14.8/lib/rspec/core/example.rb:114:in `instance_eval'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-2.14.8/lib/rspec/core/example.rb:114:in `block in run'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-2.14.8/lib/rspec/core/example.rb:254:in `with_around_each_hooks'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-2.14.8/lib/rspec/core/example.rb:111:in `run'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-2.14.8/lib/rspec/core/example_group.rb:390:in `block in run_examples'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-2.14.8/lib/rspec/core/example_group.rb:386:in `map'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-2.14.8/lib/rspec/core/example_group.rb:386:in `run_examples'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-2.14.8/lib/rspec/core/example_group.rb:371:in `run'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-2.14.8/lib/rspec/core/example_group.rb:372:in `block in run'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-2.14.8/lib/rspec/core/example_group.rb:372:in `map'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-2.14.8/lib/rspec/core/example_group.rb:372:in `run'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-2.14.8/lib/rspec/core/example_group.rb:372:in `block in run'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-2.14.8/lib/rspec/core/example_group.rb:372:in `map'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-2.14.8/lib/rspec/core/example_group.rb:372:in `run'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-2.14.8/lib/rspec/core/example_group.rb:372:in `block in run'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-2.14.8/lib/rspec/core/example_group.rb:372:in `map'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-2.14.8/lib/rspec/core/example_group.rb:372:in `run'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-2.14.8/lib/rspec/core/command_line.rb:28:in `block (2 levels) in run'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-2.14.8/lib/rspec/core/command_line.rb:28:in `map'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-2.14.8/lib/rspec/core/command_line.rb:28:in `block in run'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-2.14.8/lib/rspec/core/reporter.rb:58:in `report'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-2.14.8/lib/rspec/core/command_line.rb:25:in `run'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-2.14.8/lib/rspec/core/runner.rb:80:in `run'
# /home/travis/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-2.14.8/lib/rspec/core/runner.rb:17:in `block in autorun'
@ioquatix , I'm on it.
@ioquatix , I've rewritten your spec, but cannot push to your branch. Can one "pull-request" to a "pull-request"? :)
github, still amazing me...
Thansks to @TiagoCardoso1983 we now have a better spec.
@tarcieri I believe we are good to go on this one.
I tried using "ensure" block but it caused segfault. Not sure why. I only tested locally with 2.0.0 which had the bug. Perhaps you can suggest how to write a failing spec for this edge case.