[jitsi-dev] Deadlock in StunStack/StunClientTransaction


#1

Hi,
We recently added deadlock detection our application and it just detected a deadlock between StunStack and StunClientTransaction. You can see the stack traces of the two threads that deadlocked below (I've removed the application specific parts of the stacks):

org.ice4j.stack.StunClientTransaction.cancel(S: 404) <---- waiting for StunClientTransaction.this
org.ice4j.stack.StunClientTransaction.cancel(S: 415)
org.ice4j.stack.StunStack.cancelTransactionsForAddress(S: 256) <--- acquires clientTransactions
org.ice4j.stack.StunStack.removeSocket(S: 130)
org.ice4j.ice.LocalCandidate.free(S: 281)
org.ice4j.ice.Component.free(S: 834)
org.ice4j.ice.Component.free(S: 817)
org.ice4j.ice.IceMediaStream.free(S: 298)
org.ice4j.ice.Agent.removeStream(S: 1113)
org.ice4j.ice.Agent.free(S: 2025)

org.ice4j.stack.StunStack.removeClientTransaction(S: 669) <---- waiting for clientTransactions
org.ice4j.stack.StunClientTransaction.run(S: 301) <---- acquires StunClientTransaction.this
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java: 1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java: 615)
java.lang.Thread.run(Thread.java: 722)

As you can see locks are acquired in opposite order in each respective thread and they therefore end up waiting for each other indefinitely.

Also, if you'd like to add deadlock detection to ice4j, feel free to use our code (see attached). I had to remove some application specific parts of it so I might have messed something up but you should get the gist of it.

Best Regards
Carl Hasselskog
Degoo

DeadlockUtil.java (1.92 KB)


#2

На 27.05.2014 18:13, Carl Hasselskog написа:

We recently added deadlock detection our application and it just detected a deadlock between StunStack and StunClientTransaction. You can see the stack traces of the two threads that deadlocked below (I've removed the application specific parts of the stacks):

org.ice4j.stack.StunClientTransaction.cancel(S: 404) <---- waiting for StunClientTransaction.this
org.ice4j.stack.StunClientTransaction.cancel(S: 415)
org.ice4j.stack.StunStack.cancelTransactionsForAddress(S: 256) <--- acquires clientTransactions
org.ice4j.stack.StunStack.removeSocket(S: 130)
org.ice4j.ice.LocalCandidate.free(S: 281)
org.ice4j.ice.Component.free(S: 834)
org.ice4j.ice.Component.free(S: 817)
org.ice4j.ice.IceMediaStream.free(S: 298)
org.ice4j.ice.Agent.removeStream(S: 1113)
org.ice4j.ice.Agent.free(S: 2025)

org.ice4j.stack.StunStack.removeClientTransaction(S: 669) <---- waiting for clientTransactions
org.ice4j.stack.StunClientTransaction.run(S: 301) <---- acquires StunClientTransaction.this
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java: 1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java: 615)
java.lang.Thread.run(Thread.java: 722)

As you can see locks are acquired in opposite order in each respective thread and they therefore end up waiting for each other indefinitely.

Thank you very much for the report! We committed SVN revision 398 in response to it. Please let us know how it works for you!