Last active
September 21, 2015 17:55
-
-
Save bignacio/7a947960113775477c72 to your computer and use it in GitHub Desktop.
autoload & require deadlock
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*** Tested using JRuby 1.7.21 *** | |
Save all the files into the same directory and run | |
# jruby main.rb | |
as any good deadlock, it won't happen all the time so you can do something like this | |
# while [ true ] ; do jruby main.rb ; done | |
and wait till it hangs. | |
You can confirm the dealock with jstack | |
Once the process is hung, get its pid and run | |
jstack -l <pid> | |
you'll see something like this | |
Found one Java-level deadlock: | |
============================= | |
"Ruby-0-Thread-3: main.rb:1": | |
waiting for ownable synchronizer 0x00000007b65b9a58, (a java.util.concurrent.locks.ReentrantLock$NonfairSync), | |
which is held by "Ruby-0-Thread-2: main.rb:1" | |
"Ruby-0-Thread-2: main.rb:1": | |
waiting to lock monitor 0x00007f8832523fb8 (object 0x00000007b63ff810, a java.lang.Object), | |
which is held by "Ruby-0-Thread-3: main.rb:1" | |
Java stack information for the threads listed above: | |
=================================================== | |
"Ruby-0-Thread-3: main.rb:1": | |
at sun.misc.Unsafe.park(Native Method) | |
- parking to wait for <0x00000007b65b9a58> (a java.util.concurrent.locks.ReentrantLock$NonfairSync) | |
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) | |
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836) | |
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870) | |
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199) | |
at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:209) | |
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285) | |
... | |
"Ruby-0-Thread-2: main.rb:1": | |
at org.jruby.RubyModule$Autoload.getConstant(RubyModule.java:3825) | |
- waiting to lock <0x00000007b63ff810> (a java.lang.Object) | |
at org.jruby.RubyModule.getAutoloadConstant(RubyModule.java:3621) | |
at org.jruby.RubyModule.resolveUndefConstant(RubyModule.java:3108) | |
at org.jruby.RubyModule.getConstantAtSpecial(RubyModule.java:2968) | |
at org.jruby.RubyModule.defineOrGetClassUnder(RubyModule.java:1281) | |
at org.jruby.ast.ClassNode.interpret(ClassNode.java:134) | |
at org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105) | |
at org.jruby.ast.BlockNode.interpret(BlockNode.java:71) | |
at org.jruby.evaluator.ASTInterpreter.INTERPRET_CLASS(ASTInterpreter.java:103) | |
at org.jruby.evaluator.ASTInterpreter.evalClassDefinitionBody(ASTInterpreter.java:280) | |
at org.jruby.ast.ModuleNode.interpret(ModuleNode.java:120) | |
at org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105) | |
at org.jruby.ast.RootNode.interpret(RootNode.java:129) | |
at org.jruby.evaluator.ASTInterpreter.INTERPRET_ROOT(ASTInterpreter.java:121) | |
at org.jruby.Ruby.runInterpreter(Ruby.java:894) | |
at org.jruby.Ruby.loadFile(Ruby.java:2860) | |
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module DeadlockTest | |
class AnotherClassBase | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module DeadlockTest | |
autoload :AnotherClassBase, 'another_class_base' | |
class ClassA | |
class AnotherClass < AnotherClassBase | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module DeadlockTest | |
autoload :ClassA, 'class_a' | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'thread' | |
require 'deadlock_test' | |
puts("Starting, JRuby version: #{JRUBY_VERSION}") | |
ta = Thread.new{ | |
puts("Thread A #{JRuby.reference(Thread.current).native_thread}\n") | |
# This is not a usual thing for people to do but it can happen if an external component is loading | |
# your ruby code | |
# I first run into this problem in a storm topology (via RedStorm), which does | |
# a similar thing. I'm sure there are other ways to reproduce the same problem | |
# without a require but this | |
require 'class_a' | |
} | |
tb = Thread.new{ | |
puts("Thread B #{JRuby.reference(Thread.current).native_thread}\n") | |
o = DeadlockTest::ClassA.new | |
puts('if you see this, try again :) ') | |
} | |
ta.join | |
tb.join | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment