I have ran into a reproducible deadlock on the AWT-EventQueue thread forcing the user to kill the designer process. To reproduce it requires Debug level logging on tags.manager.gwinterface
and OutputConsole
and python print statements. This can be reproduced with a button that just logs a message (print ‘Hello World!’) on mouse enter and scroll the mouse over the button a few times. Here is the stack trace for the deadlocked threads from the thread dump.
Found one Java-level deadlock:
=============================
"AWT-EventQueue-0":
waiting for ownable synchronizer 0x00000000c24be698, (a java.util.concurrent.locks.ReentrantLock$FairSync),
which is held by "DesignerExecEngine-3"
"DesignerExecEngine-3":
waiting to lock monitor 0x00000168d3c3e100 (object 0x00000000c37d96c0, a java.io.PrintStream),
which is held by "AWT-EventQueue-0"
Java stack information for the threads listed above:
===================================================
"AWT-EventQueue-0":
at jdk.internal.misc.Unsafe.park(java.base@11.0.2/Native Method)
- parking to wait for <0x00000000c24be698> (a java.util.concurrent.locks.ReentrantLock$FairSync)
at java.util.concurrent.locks.LockSupport.park(java.base@11.0.2/Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(java.base@11.0.2/Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(java.base@11.0.2/Unknown Source)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(java.base@11.0.2/Unknown Source)
at java.util.concurrent.locks.ReentrantLock.lock(java.base@11.0.2/Unknown Source)
at ch.qos.logback.core.OutputStreamAppender.subAppend(OutputStreamAppender.java:210)
at ch.qos.logback.core.OutputStreamAppender.append(OutputStreamAppender.java:100)
at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:84)
at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:48)
at ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:270)
at ch.qos.logback.classic.Logger.callAppenders(Logger.java:257)
at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:421)
at ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:383)
at ch.qos.logback.classic.Logger.debug(Logger.java:482)
at com.inductiveautomation.ignition.common.util.LoggerEx.debug(LoggerEx.java:459)
at com.inductiveautomation.ignition.client.util.gui.OutputConsole$DocumentSizeFilter.insertString(OutputConsole.java:262)
at javax.swing.text.AbstractDocument.insertString(java.desktop@11.0.2/Unknown Source)
at com.inductiveautomation.ignition.client.util.gui.OutputConsole$ConsoleAppender.print(OutputConsole.java:216)
at com.inductiveautomation.ignition.client.util.gui.OutputConsole$ConsoleAppender.write(OutputConsole.java:208)
at com.inductiveautomation.ignition.common.util.BifurcatingOutputStream.write(BifurcatingOutputStream.java:46)
at java.io.PrintStream.write(java.base@11.0.2/Unknown Source)
- locked <0x00000000c37d96c0> (a java.io.PrintStream)
at com.inductiveautomation.ignition.common.util.BifurcatingOutputStream.write(BifurcatingOutputStream.java:46)
at java.nio.channels.Channels$WritableByteChannelImpl.write(java.base@11.0.2/Unknown Source)
- locked <0x00000000c7a67e48> (a java.lang.Object)
at org.python.core.io.StreamIO.write(StreamIO.java:134)
at org.python.core.io.BufferedWriter.flush(BufferedWriter.java:78)
at org.python.core.io.TextIOBase.flush(TextIOBase.java:168)
at org.python.core.PyFile.file_flush(PyFile.java:542)
- locked <0x00000000c7a67c08> (a org.python.core.PyFile)
at org.python.core.PyFile.flush(PyFile.java:546)
at org.python.core.StdoutWrapper.print(StdoutWrapper.java:202)
at org.python.core.StdoutWrapper.println(StdoutWrapper.java:272)
at org.python.core.Py.println(Py.java:1858)
at org.python.pycode._pyx3.f$0(<event:propertyChange>:43)
at org.python.pycode._pyx3.call_function(<event:propertyChange>)
at org.python.core.PyTableCode.call(PyTableCode.java:171)
at org.python.core.PyCode.call(PyCode.java:18)
at org.python.core.Py.runCode(Py.java:1614)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:686)
at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter.runActions(ActionAdapter.java:180)
- locked <0x00000000dba8b428> (a com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter)
at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter$ActionRunner.run(ActionAdapter.java:286)
at java.awt.event.InvocationEvent.dispatch$$$capture(java.desktop@11.0.2/Unknown Source)
at java.awt.event.InvocationEvent.dispatch(java.desktop@11.0.2/Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(java.desktop@11.0.2/Unknown Source)
at java.awt.EventQueue$4.run(java.desktop@11.0.2/Unknown Source)
at java.awt.EventQueue$4.run(java.desktop@11.0.2/Unknown Source)
at java.security.AccessController.doPrivileged(java.base@11.0.2/Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(java.base@11.0.2/Unknown Source)
at java.awt.EventQueue.dispatchEvent(java.desktop@11.0.2/Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(java.desktop@11.0.2/Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(java.desktop@11.0.2/Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(java.desktop@11.0.2/Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(java.desktop@11.0.2/Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(java.desktop@11.0.2/Unknown Source)
at java.awt.EventDispatchThread.run(java.desktop@11.0.2/Unknown Source)
"DesignerExecEngine-3":
at java.io.PrintStream.write(java.base@11.0.2/Unknown Source)
- waiting to lock <0x00000000c37d96c0> (a java.io.PrintStream)
at java.io.FilterOutputStream.write(java.base@11.0.2/Unknown Source)
at ch.qos.logback.core.joran.spi.ConsoleTarget$1.write(ConsoleTarget.java:37)
at ch.qos.logback.core.encoder.LayoutWrappingEncoder.doEncode(LayoutWrappingEncoder.java:131)
at ch.qos.logback.core.OutputStreamAppender.writeOut(OutputStreamAppender.java:187)
at ch.qos.logback.core.OutputStreamAppender.subAppend(OutputStreamAppender.java:212)
at ch.qos.logback.core.OutputStreamAppender.append(OutputStreamAppender.java:100)
at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:84)
at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:48)
at ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:270)
at ch.qos.logback.classic.Logger.callAppenders(Logger.java:257)
at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:421)
at ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:383)
at ch.qos.logback.classic.Logger.debug(Logger.java:482)
at com.inductiveautomation.ignition.common.util.LoggerEx.debug(LoggerEx.java:459)
at com.inductiveautomation.ignition.client.tags.impl.GatewayTagInterface.runPoll(GatewayTagInterface.java:111)
at com.inductiveautomation.ignition.client.tags.impl.GatewayTagInterface$$Lambda$309/0x00000001008fdc40.run(Unknown Source)
at com.inductiveautomation.ignition.common.execution.impl.BasicExecutionEngine$TrackedTask.run(BasicExecutionEngine.java:565)
at java.util.concurrent.Executors$RunnableAdapter.call(java.base@11.0.2/Unknown Source)
at java.util.concurrent.FutureTask.runAndReset$$$capture(java.base@11.0.2/Unknown Source)
at java.util.concurrent.FutureTask.runAndReset(java.base@11.0.2/Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(java.base@11.0.2/Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@11.0.2/Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@11.0.2/Unknown Source)
at java.lang.Thread.run(java.base@11.0.2/Unknown Source)
Found 1 deadlock.