Bug 136943 - [console] README: Console Deadlock when too much information written
Summary: [console] README: Console Deadlock when too much information written
Status: VERIFIED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: Debug (show other bugs)
Version: 3.2   Edit
Hardware: PC Windows XP
: P3 normal with 3 votes (vote)
Target Milestone: 3.3 M7   Edit
Assignee: Curtis Windatt CLA
QA Contact:
URL:
Whiteboard:
Keywords: readme
: 140540 169476 (view as bug list)
Depends on:
Blocks: 259107
  Show dependency tree
 
Reported: 2006-04-16 18:26 EDT by Ian Bull CLA
Modified: 2009-01-30 11:34 EST (History)
7 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ian Bull CLA 2006-04-16 18:26:12 EDT
I am writing a plugin that writes to the console of the runtime workbench.  It is working fine until I try and write a LOT of information.  At this point eclipse just seems to hang.  I enabled the debugger and it seems that in the IOConsolePartitioner class: 

In 3.2RC1 (approx line 465 in IOConsolePartitioner )
            if (fBuffer > 160000) {
                try {
                    pendingPartitions.wait();
                } catch (InterruptedException e) {
                }
            } 
The wait happens (because the buffer is large), but since only one stream is being used, no tasks are scheduled to wake this thread up.  Eclipse hangs!

The following test case will reproduce this:
public void run(IAction action) {
        MessageConsole console = null;
        MessageConsoleStream consoleOut = null;
        console = findConsole("MyConsole");
        consoleOut = console.newMessageStream();
        consoleOut.setActivateOnWrite(true);
        for ( int i = 0; i < 100000; i++) {
            consoleOut.println("a");
        }
    }
    
    private MessageConsole findConsole( String name ) {
          ConsolePlugin plugin = ConsolePlugin.getDefault();
          IConsoleManager conMan = plugin.getConsoleManager();
          IConsole[] existing = conMan.getConsoles();
          for (int i = 0; i < existing.length; i++)
             if (name.equals(existing[i].getName()))
                return (MessageConsole) existing[i];
          //no console found, so create a new one
          MessageConsole myConsole = new MessageConsole(name, null);
          conMan.addConsoles(new IConsole[]{myConsole});
          return myConsole;
    } 

Put this in an action and let it run.
Comment 1 Kevin Barnes CLA 2006-04-20 16:20:02 EDT
reproduced on N20060420-0010.

The QueueProcessingJob does the notify could be related to the way the jobs are scheduled. Probably safest to do a timed wait in a loop.

Something like: 

            while (fBuffer > 160000) { 
                try {
                    pendingPartitions.wait(500);
                } catch (InterruptedException e) {
                }
            }

Comment 2 Kevin Barnes CLA 2006-04-20 16:27:37 EDT
On second glance I realize this is really a bug in the test case, not the console. The action is hogging the UI thread trying to write, this means the console is never able to process any part of its queue. Changing the test case to use a different thread resolves the issue.

    public void run(IAction action) {
        new Thread(new Runnable() {
            public void run() {
                MessageConsole console = null;
                MessageConsoleStream consoleOut = null;
                console = findConsole("MyConsole");
                consoleOut = console.newMessageStream();
                consoleOut.setActivateOnWrite(true);
                for ( int i = 0; i < 100000; i++) {
                    consoleOut.println("a");
                }
            }
        }).start();
    }
Comment 3 Ian Bull CLA 2006-04-20 17:01:31 EDT
So if I open a large text file and dump it to the console, I have to do this in a separate thread?  This seems a little strange.  

The test case works fine for System.out.println, and it works for any other stream. I agree that the task is *hogging* the UI thread, but should this really cause a deadlock?  (it's not like it just gets slow, it actually freezes Eclipse).

- ian
Comment 4 Charles Tuckey CLA 2006-10-05 18:31:30 EDT
We have just run into this problem on Linux. I don't understand why this bug was closed. This is an issue where the UI can just stop responding. There are no indicators to the programmer that he needs to be careful about how much stuff gets written to a console. It seems to me that this is forcing the programmer to either always run a separate thread when writing to the console or to keep track himself how much has been written there.

At the very least, there needs to be some documentation about this in the API javadoc.
Comment 5 Darin Wright CLA 2006-10-05 22:54:24 EDT
Re-opening. We should add some javadoc to the applicable API .
Comment 6 Koshin Mariano CLA 2006-11-20 19:31:06 EST
  We encountered the same problem when trying to print the state of objects (more than 1000) to the console using MessageConsoleStream.println(). 


Comment 7 Darin Wright CLA 2007-04-18 15:13:14 EDT
Updated javadoc to indicate clients should avoid writing lots of output the console output stream in the UI thread.

Changes to IOConsole, MessageConsole, IOConsoleOutputStream, and MessageConsoleStream.
Comment 8 Darin Wright CLA 2007-04-18 15:13:29 EDT
Please verify, Curtis.
Comment 9 Darin Wright CLA 2007-04-18 15:16:08 EDT
*** Bug 140540 has been marked as a duplicate of this bug. ***
Comment 10 Curtis Windatt CLA 2007-04-18 16:34:01 EDT
Verified javadoc changes.
Comment 11 Darin Wright CLA 2007-05-02 14:52:02 EDT
*** Bug 169476 has been marked as a duplicate of this bug. ***
Comment 12 Daniel Friederich CLA 2007-07-02 07:28:55 EDT
I did just run across this issue too.
The current fix of this bug is to just to warn the programmer:

Clients should avoid writing large amounts of output to this stream in the UI thread. The console needs to process the output in the UI thread and if the client hogs the UI thread writing output to the console, the console will not be able to process the output.

While I agree that clients should not call that code on the UI thread, the current implementation is really dangerous, waiting for others to run into this issue too. The description is also way to soft, it just states that programmers should do something, but it does not clearly state that they are about to run into a deadlock. And worst, usually not the programmers but the users of their app are the ones with the huge console output, so this bug is likely to end up in the final applications.

To summarize, I don't think that the current javadoc change really fixes this issue. The code must not deadlock no matter on which thread it was called. If it must not ever be called on the UI thread, then this must explicitly be documented (and best, also asserted/tested at runtime), independent of the amount of text to print.
Comment 13 Ed Willink CLA 2007-07-02 07:35:21 EDT
If 6 different developers all hit this limitation, then I think we need a better solution than Javadoc.
Comment 14 Daniel Friederich CLA 2007-07-02 13:16:42 EDT
I think there are a lot more than 6.

When searching through Bugzilla, al least all those bugs appear to be caused by this behavior too:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=139424
https://bugs.eclipse.org/bugs/show_bug.cgi?id=194456
https://bugs.eclipse.org/bugs/show_bug.cgi?id=147384
https://bugs.eclipse.org/bugs/show_bug.cgi?id=140540
https://bugs.eclipse.org/bugs/show_bug.cgi?id=169476
https://bugs.eclipse.org/bugs/show_bug.cgi?id=133679


I think noone is expecting the current behavior and we are just fixing all the clients instead of actually fix the broken implementation in IOConsolePartitioner.
Comment 15 Curtis Windatt CLA 2009-01-30 11:34:51 EST
This has been fixed in 3.5 M5 and 3.4.2.  See bug 259107.  Please retry your test cases and file bugs for any problems.