Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 333014 - SimpleCommandOperation.readLine() returns empty on too fast consequent executions
Summary: SimpleCommandOperation.readLine() returns empty on too fast consequent execut...
Status: REOPENED
Alias: None
Product: Target Management
Classification: Tools
Component: RSE (show other bugs)
Version: unspecified   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: Future   Edit
Assignee: Anna Dushistova CLA
QA Contact: Martin Oberhuber CLA
URL:
Whiteboard:
Keywords:
Depends on: 274153
Blocks:
  Show dependency tree
 
Reported: 2010-12-21 08:45 EST by Samuel Lampa CLA
Modified: 2012-05-22 15:03 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Samuel Lampa CLA 2010-12-21 08:45:15 EST
Build Identifier: 20100617-1415

I'm tryng to execute a command on a remote system via SSH and read the output.

The problem: If running the readLine() function of an SimpleCommandOperation object in a loop with no or almost no sleep between the iterations, the function gives empty results for most of the iterations, and only occasionally returns another line of the stdout content. When introducing a sleep of a few ms, the number of empty results decreases, and around 15-25 ms, it seems like a correct result is returned for every iteration.

At some stage I did also get an exception telling that "pipe closed", when running the iteration without sleep, though I haven't been able to reproduce it later.

I'm running 32bit Ubuntu 10.10 (kernel 2.6.35-23-generic), with java-6-sun-1.6.0.22, on a 1.3 GHz Dual-Core laptop.

The remote system is running 64bit Scientific Linux (kernel 2.6.18-194.17.4.el5)

Reproducible: Always

Steps to Reproduce:
1. Open an SSH connection to a remote Linux/Unix host
2. Run some code like the following (replacing "[the-host-name-of-your-host]" with your host, and the "projinfo" command with something which is available on your system):

	ISystemRegistry reg = SystemStartHere.getSystemRegistry();
	IHost[] hosts = reg.getHosts();
	if (hosts.length == 0) {
		System.out.println("No host names found!");
	}
	for (IHost host : hosts) {
		String hostAlias = host.getAliasName();
		if (hostAlias.equals("[the-host-name-of-your-host]")) {
			IRemoteCmdSubSystem cmdss = RemoteCommandHelpers.getCmdSubSystem(host);
			SimpleCommandOperation simpleCommandOp = new SimpleCommandOperation(cmdss, new RemoteFileEmpty(), true);
			try {
				allOutput = "";
				temp = "";
				simpleCommandOp.runCommand("projinfo", true);
				for (int i=0;i<100;i++) {
					temp = "";
					temp = simpleCommandOp.readLine(false);
					if (temp == null) {
						System.out.println("Temp is nul&#314;!");
					} else if (temp.equals("")) {
						System.out.println("*** readLine returned empty result!");
					} else {
						System.out.println("Temp: " + temp);
						allOutput += temp + "\n";
					}		
					try {
						Thread.sleep(100);
					} catch (Exception e4) {
						e4.printStackTrace();
					}
				}
				System.out.println(allOutput);
			} catch (Exception e3) {
				// TODO Auto-generated catch block
				e3.printStackTrace();
			}
			break;
		}
	}


3. Watch for an excess of "*** readLine returned empty result" output.
4. Modify the line "Thread.sleep(0);", with values between 0-25 (or so), and see how the amount of empty results change.
Comment 1 David McKnight CLA 2010-12-22 09:09:48 EST
SimpleCommandOperation.readLine() takes a boolean argument that indicates whether to wait for output or not.  In some cases, output is assumed to already be available (without any wait) - those are the times where the use of the false argument makes sense.  However, if you need to wait for output, you can pass in true instead as is done with a modified version of your example code here:

      ....
      for (int i=0;i<100;i++) {
         temp = "";
         temp = simpleCommandOp.readLine(true); // changed this from false to true
         if (temp == null) {
            System.out.println("Temp is nul&#314;!");
      ...
Comment 2 Samuel Lampa CLA 2010-12-22 10:08:12 EST
Ok, tried this now, and I realize that this is where I get the "pipe closed" exception, if using no sleep (works fine with 25 ms sleep). From the error log:

java.io.IOException: Pipe closed
	at java.io.PipedInputStream.read(PipedInputStream.java:291)
	at java.io.PipedInputStream.read(PipedInputStream.java:361)
	at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
	at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
	at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
	at java.io.InputStreamReader.read(InputStreamReader.java:167)
	at java.io.BufferedReader.fill(BufferedReader.java:136)
	at java.io.BufferedReader.read(BufferedReader.java:157)
	at org.eclipse.rse.internal.services.shells.TerminalServiceShellOutputReader.internalReadLine(TerminalServiceShellOutputReader.java:60)
	at org.eclipse.rse.services.shells.AbstractHostShellOutputReader.handle(AbstractHostShellOutputReader.java:74)
	at org.eclipse.rse.services.shells.AbstractHostShellOutputReader.run(AbstractHostShellOutputReader.java:180)
Comment 3 David McKnight CLA 2010-12-22 15:24:44 EST
(In reply to comment #2)
> Ok, tried this now, and I realize that this is where I get the "pipe closed"
> exception, if using no sleep (works fine with 25 ms sleep). From the error log:
> 
> java.io.IOException: Pipe closed
>     at java.io.PipedInputStream.read(PipedInputStream.java:291)
>     at java.io.PipedInputStream.read(PipedInputStream.java:361)
>     at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
>     at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
>     at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
>     at java.io.InputStreamReader.read(InputStreamReader.java:167)
>     at java.io.BufferedReader.fill(BufferedReader.java:136)
>     at java.io.BufferedReader.read(BufferedReader.java:157)
>     at
> org.eclipse.rse.internal.services.shells.TerminalServiceShellOutputReader.internalReadLine(TerminalServiceShellOutputReader.java:60)
>     at
> org.eclipse.rse.services.shells.AbstractHostShellOutputReader.handle(AbstractHostShellOutputReader.java:74)
>     at
> org.eclipse.rse.services.shells.AbstractHostShellOutputReader.run(AbstractHostShellOutputReader.java:180)


I tried this out with dstore and local shells and was not able to reproduce the exception.  It only seems to occur when using SSH/Terminals, despite the fact that TerminalServiceShellOutputReader is essentially the same code as it's local counterpart.
Comment 4 Anna Dushistova CLA 2011-05-12 06:30:21 EDT
I believe that was fixed with the bug 274153. Please reopen if that is not the case.
Comment 5 Martin Oberhuber CLA 2011-05-25 06:15:36 EDT
Marking as RC2 since we didn't formally release RC1.
Comment 6 Martin Oberhuber CLA 2011-05-25 06:17:26 EDT
Is this maybe related to bug 279837 ?
Comment 7 Samuel Lampa CLA 2011-08-02 06:34:21 EDT
(In reply to comment #3)
> (In reply to comment #2)
> > Ok, tried this now, and I realize that this is where I get the "pipe closed"
> > exception, if using no sleep (works fine with 25 ms sleep). From the error log:
> > 
> > java.io.IOException: Pipe closed
> >     at java.io.PipedInputStream.read(PipedInputStream.java:291)
> >     at java.io.PipedInputStream.read(PipedInputStream.java:361)
> >     at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
> >     at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
> >     at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
> >     at java.io.InputStreamReader.read(InputStreamReader.java:167)
> >     at java.io.BufferedReader.fill(BufferedReader.java:136)
> >     at java.io.BufferedReader.read(BufferedReader.java:157)
> >     at
> > org.eclipse.rse.internal.services.shells.TerminalServiceShellOutputReader.internalReadLine(TerminalServiceShellOutputReader.java:60)
> >     at
> > org.eclipse.rse.services.shells.AbstractHostShellOutputReader.handle(AbstractHostShellOutputReader.java:74)
> >     at
> > org.eclipse.rse.services.shells.AbstractHostShellOutputReader.run(AbstractHostShellOutputReader.java:180)
> 
> 
> I tried this out with dstore and local shells and was not able to reproduce the
> exception.  It only seems to occur when using SSH/Terminals, despite the fact
> that TerminalServiceShellOutputReader is essentially the same code as it's
> local counterpart.

I tried this now, and this Exception (exactly same call stack) still occurs for me. Only when I put 15-25 ms sleep between the consecutive readLine() calls, I can avoid the "pipe closed" Exception.
Comment 8 Samuel Lampa CLA 2011-08-02 06:41:12 EDT
Forgot to add version details:

RSE End-User Runtime: 3.3.0.v20110601...
RSE Core:             3.3.0.v20110601...
RSE SSH Services:     3.0.300.v20110601...
Comment 9 Samuel Lampa CLA 2011-08-02 07:50:15 EDT
(In reply to comment #0)
> The problem: If running the readLine() function of an SimpleCommandOperation
> object in a loop with no or almost no sleep between the iterations, the
> function gives empty results for most of the iterations, and only occasionally
> returns another line of the stdout content. When introducing a sleep of a few
> ms, the number of empty results decreases, and around 15-25 ms, it seems like 

Clarification: This initial problem with empty lines from readLine(), I am not been able to reproduce now. Only the "pipe closed" one remains.
Comment 10 Samuel Lampa CLA 2011-08-02 08:05:01 EDT
(In reply to comment #7)
> (In reply to comment #3)
> > (In reply to comment #2)
> > > Ok, tried this now, and I realize that this is where I get the "pipe closed"
> > > exception, if using no sleep (works fine with 25 ms sleep). From the error log:
> > > 
> > > java.io.IOException: Pipe closed
> > >     at java.io.PipedInputStream.read(PipedInputStream.java:291)
> > >     at java.io.PipedInputStream.read(PipedInputStream.java:361)
> > >     at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
> > >     at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
> > >     at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
> > >     at java.io.InputStreamReader.read(InputStreamReader.java:167)
> > >     at java.io.BufferedReader.fill(BufferedReader.java:136)
> > >     at java.io.BufferedReader.read(BufferedReader.java:157)
> > >     at
> > > org.eclipse.rse.internal.services.shells.TerminalServiceShellOutputReader.internalReadLine(TerminalServiceShellOutputReader.java:60)
> > >     at
> > > org.eclipse.rse.services.shells.AbstractHostShellOutputReader.handle(AbstractHostShellOutputReader.java:74)
> > >     at
> > > org.eclipse.rse.services.shells.AbstractHostShellOutputReader.run(AbstractHostShellOutputReader.java:180)
> > 
> > 
> > I tried this out with dstore and local shells and was not able to reproduce the
> > exception.  It only seems to occur when using SSH/Terminals, despite the fact
> > that TerminalServiceShellOutputReader is essentially the same code as it's
> > local counterpart.
> 
> I tried this now, and this Exception (exactly same call stack) still occurs for
> me. Only when I put 15-25 ms sleep between the consecutive readLine() calls, I
> can avoid the "pipe closed" Exception.

Some more testing revealed that the "Pipe closed" exception has nothing to do with the sleep time between the readLine() calls. It occurs every time, if the runAsShell parameter is set to true.
Comment 11 Martin Oberhuber CLA 2011-08-02 08:29:36 EDT
As Anna mentioned on comment 4, I think that this is related to bug 274153 which got fixed only after 3.3.

Please upgrade to the latest and retry -
Downloads:
http://download.eclipse.org/tm/downloads/drops/I20110722-1330/index.php
Update Site:
http://download.eclipse.org/tm/updates/3.3milestones
Comment 12 Samuel Lampa CLA 2011-08-02 08:53:41 EDT
(In reply to comment #11)
> As Anna mentioned on comment 4, I think that this is related to bug 274153
> which got fixed only after 3.3.
> 
> Please upgrade to the latest and retry -
> Downloads:
> http://download.eclipse.org/tm/downloads/drops/I20110722-1330/index.php
> Update Site:
> http://download.eclipse.org/tm/updates/3.3milestones

Ah, sorry didn't realize I had to use this other update site (was using http://download.eclipse.org/tm/updates/3.3/)

Same error though, with:
RSE Core	3.3.1.R33x_v201106281309-7a7JFZ1F9Dyo8ynwUvjic3wHaNT
RSE SSH Services 3.0.301.R33x_v201106281309-7A3F9xAGGB5k0C7KEATN92641
Comment 13 Samuel Lampa CLA 2011-08-02 08:55:06 EDT
(In reply to comment #12)
> (In reply to comment #11)
> > As Anna mentioned on comment 4, I think that this is related to bug 274153
> > which got fixed only after 3.3.
> > 
> > Please upgrade to the latest and retry -
> > Downloads:
> > http://download.eclipse.org/tm/downloads/drops/I20110722-1330/index.php
> > Update Site:
> > http://download.eclipse.org/tm/updates/3.3milestones
> 
> Ah, sorry didn't realize I had to use this other update site (was using
> http://download.eclipse.org/tm/updates/3.3/)
> 
> Same error though, with:
> RSE Core    3.3.1.R33x_v201106281309-7a7JFZ1F9Dyo8ynwUvjic3wHaNT
> RSE SSH Services 3.0.301.R33x_v201106281309-7A3F9xAGGB5k0C7KEATN92641

Well, doesn't seem like I get the same version from the update site (20110628 vs 20110722) ...
Comment 14 Samuel Lampa CLA 2011-08-02 09:09:30 EDT
(In reply to comment #13)
> (In reply to comment #12)
> > (In reply to comment #11)
> > > As Anna mentioned on comment 4, I think that this is related to bug 274153
> > > which got fixed only after 3.3.
> > > 
> > > Please upgrade to the latest and retry -
> > > Downloads:
> > > http://download.eclipse.org/tm/downloads/drops/I20110722-1330/index.php
> > > Update Site:
> > > http://download.eclipse.org/tm/updates/3.3milestones
> > 
> > Ah, sorry didn't realize I had to use this other update site (was using
> > http://download.eclipse.org/tm/updates/3.3/)
> > 
> > Same error though, with:
> > RSE Core    3.3.1.R33x_v201106281309-7a7JFZ1F9Dyo8ynwUvjic3wHaNT
> > RSE SSH Services 3.0.301.R33x_v201106281309-7A3F9xAGGB5k0C7KEATN92641
> 
> Well, doesn't seem like I get the same version from the update site (20110628
> vs 20110722) ...

But, the error is still there even if I download and install manually.