Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

#1286 Console: InterruptedException on subprocess termination

closed-fixed
Alan Ezust
None
5
2010-12-29
2010-01-28
Marcelo Vanzin
No

When cleaning up after a child process is done, the Console plugin interrupts all the threads it spawns to read stdout / stderr. Problem is, it doesn't check to see whether those threads are really blocked, and sometimes interrupts valid operations. For example, simply changing the mode of the current buffer (with "chmod blah $f") causes the thread handling the EditBus message that Console itself triggers to be interrupted:

6:53:00 PM [Thread-20] [error] EditBus: java.lang.InterruptedException
6:53:00 PM [Thread-20] [error] EditBus: at java.lang.Object.wait(Native Method)
6:53:00 PM [Thread-20] [error] EditBus: at java.lang.Object.wait(Object.java:485)
6:53:00 PM [Thread-20] [error] EditBus: at java.awt.EventQueue.invokeAndWait(EventQueue.java:992)
6:53:00 PM [Thread-20] [error] EditBus: at javax.swing.SwingUtilities.invokeAndWait(SwingUtilities.java:1323)
6:53:00 PM [Thread-20] [error] EditBus: at org.gjt.sp.jedit.EditBus.send(EditBus.java:211)
6:53:00 PM [Thread-20] [error] EditBus: at org.gjt.sp.jedit.BufferHistory.notifyChange(BufferHistory.java:406)
6:53:00 PM [Thread-20] [error] EditBus: at org.gjt.sp.jedit.BufferHistory.setEntry(BufferHistory.java:115)
6:53:00 PM [Thread-20] [error] EditBus: at org.gjt.sp.jedit.EditPane.saveCaretInfo(EditPane.java:361)
6:53:00 PM [Thread-20] [error] EditBus: at org.gjt.sp.jedit.visitors.SaveCaretInfoVisitor.visit(SaveCaretInfoVisitor.java:36)
6:53:00 PM [Thread-20] [error] EditBus: at org.gjt.sp.jedit.View.visit(View.java:1321)
6:53:00 PM [Thread-20] [error] EditBus: at org.gjt.sp.jedit.jEdit.visit(jEdit.java:2867)
6:53:00 PM [Thread-20] [error] EditBus: at org.gjt.sp.jedit.jEdit.checkBufferStatus(jEdit.java:2259)
6:53:00 PM [Thread-20] [error] EditBus: at org.gjt.sp.jedit.jEdit.checkBufferStatus(jEdit.java:2237)
6:53:00 PM [Thread-20] [error] EditBus: at console.ConsoleProcess.threadDone(ConsoleProcess.java:315)
6:53:00 PM [Thread-20] [error] EditBus: at console.StreamThread.run(StreamThread.java:187)

(This happens both with my patch to fire EditBus messages in the AWT and without it.)

Discussion

  • Alan Ezust
    Alan Ezust
    2010-01-30

    It looks like since your change with how editbus handlers are sent, there is a more serious problem with console - for me it locks up whenever there are errors as a result of the output.
    But there are some other screwy things about how the end of the subprocess are handled, I know. And also hard for me to reproduce since they are very timing sensitive, so I am not even sure how to debug this. Help?

     
  • Marcelo Vanzin
    Marcelo Vanzin
    2010-01-30

    The hang is a deadlock caused by ErrorList because of the new EditBus behavior:

    "Thread-14" prio=10 tid=0x097bf400 nid=0x11f6 in Object.wait() [0xe990b000]
    java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0xf3397930> (a java.awt.EventQueue$1AWTInvocationLock)
    at java.lang.Object.wait(Object.java:485)
    at java.awt.EventQueue.invokeAndWait(EventQueue.java:992)
    - locked <0xf3397930> (a java.awt.EventQueue$1AWTInvocationLock)
    at javax.swing.SwingUtilities.invokeAndWait(SwingUtilities.java:1323)
    at org.gjt.sp.jedit.EditBus.send(EditBus.java:211)
    at errorlist.ErrorSource.registerErrorSource(ErrorSource.java:58)
    - locked <0xf07a5da0> (a java.util.Vector)

    "AWT-EventQueue-0" prio=10 tid=0x096a4000 nid=0x11a1 waiting for monitor entry [0xeab55000]
    java.lang.Thread.State: BLOCKED (on object monitor)
    at errorlist.ErrorSource.getErrorSources(ErrorSource.java:93)
    - waiting to lock <0xf07a5da0> (a java.util.Vector)

     
  • Today I got bitten by the deadlock. It was now fixed in r17157 of
    ErrorList.

     
  • Today I got bitten by the exact InterruptedException.

    After some investigation, it turned out that the problems is calling
    interrupt() in StreamThread#abort() where (currentThread() == this).

    It does nothing but sets the interrupt status of the thread, and
    InterruptedException will be thrown when the thread goes into
    Object#wait() after that.
    http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Thread.html#interrupt%28%29
    > If none of the previous conditions hold then this thread's interrupt
    > status will be set.
    http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html#wait%28%29
    > Throws: InterruptedException - if another thread interrupted the
    > current thread before or while the current thread was waiting for a
    > notification.
    (note the part "*before* or while")
    The change of EditBus just increased the chance of this senario with
    implicit addition of Object#wait() under the hood of invokeAndWait() as
    shown in the stack trace.

    Now I have started to solve the puzzle of the subprocess termination in
    ConsoleProcess ...

     
    • assigned_to: nobody --> k_satoda
    • summary: Console interrupting stdout / stderr threads too soon --> Console: InterruptedException on subprocess termination
     
    • assigned_to: k_satoda --> ezust
    • status: open --> closed-fixed