Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 286162

Summary: Debug core logs spawner IO exception when running C/C++ executable on Linux
Product: [Tools] CDT Reporter: Jeff Johnston <jjohnstn>
Component: cdt-debugAssignee: Anton Leherbauer <aleherb+eclipse>
Status: RESOLVED FIXED QA Contact: Ken Ryall <ken.ryall>
Severity: normal    
Priority: P3 CC: aleherb+eclipse, cdtdoug, jamesblackburn+eclipse, marc.khouzam, Michael_Rennie, mober.at+eclipse, pawel.1.piech
Version: 6.0   
Target Milestone: 7.0.2   
Hardware: PC   
OS: Linux   
Whiteboard:
Attachments:
Description Flags
Use PTY I/O.
none
Spawner to use PTY streams and ignore error on close
none
Spawner to upse PTY streams and ignore error on close, plus dummy mode for stderr. pawel.1.piech: iplog-

Description Jeff Johnston CLA 2009-08-10 15:01:48 EDT
When running a linux a.out executable via the Run as... Local C/C++ executable pop-up menu, the executable runs successfully, but an exception is logged as follows:

java.io.IOException: read error
        at org.eclipse.cdt.utils.spawner.SpawnerInputStream.read0(Native Method)
        at org.eclipse.cdt.utils.spawner.SpawnerInputStream.read(SpawnerInputStream.java:66)
        at java.io.BufferedInputStream.read1(BufferedInputStream.java:273)
        at java.io.BufferedInputStream.read(BufferedInputStream.java:334)
        at java.io.FilterInputStream.read(FilterInputStream.java:107)
        at org.eclipse.debug.internal.core.OutputStreamMonitor.read(OutputStreamMonitor.java:144)
        at org.eclipse.debug.internal.core.OutputStreamMonitor.access$1(OutputStreamMonitor.java:134)
        at org.eclipse.debug.internal.core.OutputStreamMonitor$1.run(OutputStreamMonitor.java:207)
        at java.lang.Thread.run(Thread.java:636)

Is this related to https://bugs.eclipse.org/bugs/show_bug.cgi?id=225272 ?

This is using the upstream downloaded CDT 6 from the Galileo update site and OpenJDK 1.6: java-1.6.0-openjdk-1.6.0.0-20.b16.fc10.i386 running under downloaded Eclipse 3.5 SDK for linux.  I am running on Fedora 10.

This bug was triggered by creating and running the Hello World C template project output.
Comment 1 Martin Oberhuber CLA 2010-12-15 05:56:07 EST
We still see this with Helios SR1, any ideas?
Comment 2 James Blackburn CLA 2010-12-15 06:06:26 EST
*** Bug 315259 has been marked as a duplicate of this bug. ***
Comment 3 James Blackburn CLA 2010-12-15 06:07:38 EST
This happens when the process tears down while the input stream is still connected. 
See also the comments on Bug 315259
Comment 4 Martin Oberhuber CLA 2010-12-15 06:36:41 EST
Looks like the exception is not that exceptional after all :)

Perhaps it should just be logged as a warning, and without backtrace, until the "Process already terminated" condition can be checked reliably?
Comment 5 James Blackburn CLA 2010-12-15 06:43:49 EST
(In reply to comment #4)
> Looks like the exception is not that exceptional after all :)
> 
> Perhaps it should just be logged as a warning, and without backtrace, until the
> "Process already terminated" condition can be checked reliably?

The only CDT code here is the SpawnerInputStream which is correctly throwing the IOException on read failure.

The exception is logged by platform debug.core OutputStreamMonitor

if (!fKilled) {
	DebugPlugin.log(ioe);
}

so whether the exception is logged at different severity, or the issue fixed in platform, it's likely not a CDT bug. 

I think I was wrong to mark the platform bug as duplicate of this in the first place. Re-assigning.
Comment 6 Martin Oberhuber CLA 2010-12-15 06:51:06 EST
Can't the SpawnerInputStream detect the difference between "Read failure" and "End of Stream / Stream Closed" ?
Comment 7 James Blackburn CLA 2010-12-15 07:08:17 EST
(In reply to comment #6)
> Can't the SpawnerInputStream detect the difference between "Read failure" and
> "End of Stream / Stream Closed" ?

The I/O exception is thrown from JNI code io.c. It looks like this already checks for end of stream:

    status = read( fd, data, data_len );
    (*env)->ReleaseByteArrayElements(env, buf, data, 0);

    if (status == 0) {
        /* EOF. */
        status = -1;
    } else if (status == -1) {
        /* Error, toss an exception */
        jclass exception = (*env)->FindClass(env, "java/io/IOException");
        if (exception == NULL) {
            /* Give up.  */
            return -1;
        }
        (*env)->ThrowNew(env, exception, "read error");
    }

This seems to conform to man 2 read (though it could be more helpful in telling us what the errno is).  Also rebuilding the natives for every platform can be a real pain...

Deeper investigation is needed to work out the real source of the issue.
Comment 8 Anton Leherbauer CLA 2010-12-15 11:31:29 EST
The errno is EIO. It only happens when a PTY is used, ie. when "Connect process I/O to a terminal" is checked in the launch config.
I am not sure how to avoid the error, maybe it should be simply ignored when reading from a PTY.
Comment 9 Pawel Piech CLA 2010-12-15 12:46:03 EST
Oops, I should have added the patch from bug Bug 315259 comment #5 here.  However, after running with the fix I still see the problem intermittently.  

If the SpawnerInputStream would throw EOF instead of a generic IOException, we could use it to ignore the error and not log it.

(In reply to comment #8)
> The errno is EIO. It only happens when a PTY is used, ie. when "Connect process
> I/O to a terminal" is checked in the launch config.
> I am not sure how to avoid the error, maybe it should be simply ignored when
> reading from a PTY.

In this case PTY is not used, so the "Connect I/O to a terminal" check box is misleading (it's only connected to the console view).  Although connecting to a terminal emulator is a feature that's been requested in another bug I think.
Comment 10 Anton Leherbauer CLA 2010-12-16 02:37:59 EST
(In reply to comment #9)
> In this case PTY is not used, so the "Connect I/O to a terminal" check box is
> misleading (it's only connected to the console view).  Although connecting to a
> terminal emulator is a feature that's been requested in another bug I think.

It is not connected to a terminal emulator, but it still uses a PTY.  And that makes the difference in this case (whether the I/O error occurs or not).
Comment 11 Pawel Piech CLA 2010-12-16 10:56:06 EST
Created attachment 185334 [details]
Use PTY I/O.

(In reply to comment #10)
> It is not connected to a terminal emulator, but it still uses a PTY.  And that
> makes the difference in this case (whether the I/O error occurs or not).

I see, so we're fooling the application to think that it's talking to a terminal but on the client side we're hooking it up only to a console.  Fair enough :-)

Would it make sense then to use ptyio.c to handle the input output streaming?  MIInferiorProcess does this when debugging.  This patch hacks this change in, but when I use it I get a different exception on close:

java.io.IOException: close error
at org.eclipse.cdt.utils.pty.PTYInputStream.close(PTYInputStream.java:79)
at java.io.BufferedInputStream.close(BufferedInputStream.java:468)
at org.eclipse.debug.internal.core.OutputStreamMonitor.read(OutputStreamMonitor.java:183)
at org.eclipse.debug.internal.core.OutputStreamMonitor.access$1(OutputStreamMonitor.java:134)
at org.eclipse.debug.internal.core.OutputStreamMonitor$1.run(OutputStreamMonitor.java:207)
at java.lang.Thread.run(Thread.java:636)
Comment 12 Anton Leherbauer CLA 2010-12-17 04:03:56 EST
(In reply to comment #11)
> I see, so we're fooling the application to think that it's talking to a
> terminal but on the client side we're hooking it up only to a console.  Fair
> enough :-)
The reason is to make stdout line buffered.  Otherwise it would be fully buffered and we would get complaints about program output not displayed in the console as we get them for windows.

> Would it make sense then to use ptyio.c to handle the input output streaming? 
read0() in ptyio.c simply ignores any error.  I guess the reason is exactly the error we see today.  The bug IMO is that Spawner does not return the PTY*Streams when a pty is used.  This would also make this patch obsolete, I think.

> MIInferiorProcess does this when debugging.  This patch hacks this change in,
> but when I use it I get a different exception on close:
If we ignore any error on read, it should be just fair to ignore any error on close as well.  Nobody would care about such an error anyway.
Comment 13 Anton Leherbauer CLA 2010-12-17 04:15:58 EST
Created attachment 185407 [details]
Spawner to use PTY streams and ignore error on close

This fixes it for me.
Comment 14 Martin Oberhuber CLA 2010-12-17 04:27:06 EST
Looks nice and clean to me - thanks Toni!

When I get it right,
- Original behavior is preserved in case no PTY is used
  - Real read errors are still reported, but only when no PTY is used, since
    PTY has always ignored errors on read
- Errors on close are no longer reported since properly handled in 
  PTYInputStream, nobody would care about an error when closing an inputstream
  anyways.

Correct?

If the patch is approved and tests OK, we'd like to see it backported to Helios SR2.
Comment 15 Anton Leherbauer CLA 2010-12-17 05:27:55 EST
(In reply to comment #14)
> Looks nice and clean to me - thanks Toni!
> 
> When I get it right,
> - Original behavior is preserved in case no PTY is used
>   - Real read errors are still reported, but only when no PTY is used, since
>     PTY has always ignored errors on read
> - Errors on close are no longer reported since properly handled in 
>   PTYInputStream, nobody would care about an error when closing an inputstream
>   anyways.
> 
> Correct?

Correct.

> If the patch is approved and tests OK, we'd like to see it backported to Helios
> SR2.

Should be no problem.
Comment 16 Pawel Piech CLA 2010-12-17 17:21:26 EST
Created attachment 185465 [details]
Spawner to upse PTY streams and ignore error on close, plus dummy mode for stderr.

(In reply to comment #12)
> > Would it make sense then to use ptyio.c to handle the input output streaming? 
> read0() in ptyio.c simply ignores any error.  I guess the reason is exactly the
> error we see today.  The bug IMO is that Spawner does not return the
> PTY*Streams when a pty is used.  This would also make this patch obsolete, I
> think.
I agree.  There's one more detail though.  If the PTY is configured to channel stderr to the PTY, then the error stream from the spawner should be stubbed.
 
> > MIInferiorProcess does this when debugging.  This patch hacks this change in,
> > but when I use it I get a different exception on close:
> If we ignore any error on read, it should be just fair to ignore any error on
> close as well.  Nobody would care about such an error anyway.
It'd be nice to understand why these errors are thrown, but oh well.
Comment 17 Anton Leherbauer CLA 2010-12-20 03:14:06 EST
(In reply to comment #16)
> Created an attachment (id=185465) [details]
> Spawner to upse PTY streams and ignore error on close, plus dummy mode for
> stderr.
> 
> (In reply to comment #12)
> > > Would it make sense then to use ptyio.c to handle the input output streaming? 
> > read0() in ptyio.c simply ignores any error.  I guess the reason is exactly the
> > error we see today.  The bug IMO is that Spawner does not return the
> > PTY*Streams when a pty is used.  This would also make this patch obsolete, I
> > think.
> I agree.  There's one more detail though.  If the PTY is configured to channel
> stderr to the PTY, then the error stream from the spawner should be stubbed.

I think I understand why the error stream should be stubbed in this case, but this seems to fix a problem unrelated to this bug, right?
And why don't you simply return -1 from read().  That should be enough for a NullInputStream.

> > > MIInferiorProcess does this when debugging.  This patch hacks this change in,
> > > but when I use it I get a different exception on close:
> > If we ignore any error on read, it should be just fair to ignore any error on
> > close as well.  Nobody would care about such an error anyway.
> It'd be nice to understand why these errors are thrown, but oh well.

The error is system dependent.  E.g. I believe there is no such error on Solaris.
Comment 18 Pawel Piech CLA 2010-12-20 11:40:36 EST
(In reply to comment #17)
> I think I understand why the error stream should be stubbed in this case, but
> this seems to fix a problem unrelated to this bug, right?
> And why don't you simply return -1 from read().  That should be enough for a
> NullInputStream.
It could be handled as a separate bug.  At first I thought that were not handling the error stream correctly for the use case in this bug.  After an investigation I found that it's only the non-console view use that is affected.  In either case though we should probably take care of it right away since we're changing how the basic Spawner class works.

I didn't even think to try just returning -1 because I thought this would cause all the streams to be closed.  But this doesn't seem to be the case.  So I agree, it should just return -1.
Comment 19 Anton Leherbauer CLA 2010-12-21 03:27:15 EST
(In reply to comment #18)
> (In reply to comment #17)
> > I think I understand why the error stream should be stubbed in this case, but
> > this seems to fix a problem unrelated to this bug, right?
> > And why don't you simply return -1 from read().  That should be enough for a
> > NullInputStream.
> It could be handled as a separate bug.  At first I thought that were not
> handling the error stream correctly for the use case in this bug.  After an
> investigation I found that it's only the non-console view use that is affected.
>  In either case though we should probably take care of it right away since
> we're changing how the basic Spawner class works.

I think a separate bug would be good - just for the records.  We can still fix both bugs at the same time.

> I didn't even think to try just returning -1 because I thought this would cause
> all the streams to be closed.  But this doesn't seem to be the case.  So I
> agree, it should just return -1.

Good to know, thanks.
I'll adjust the patch and commit it.
Comment 20 Anton Leherbauer CLA 2010-12-22 04:50:30 EST
Fixed in HEAD and cdt_7_0.
Comment 22 Anton Leherbauer CLA 2011-04-01 05:12:14 EDT
*** Bug 231815 has been marked as a duplicate of this bug. ***
Comment 23 Martin Oberhuber CLA 2011-09-14 10:59:46 EDT
CQ:WIND00249939