Deadlocks in ExpectOutputStream
Per Allansson
per@appgate.com
Fri, 16 Jan 2004 09:54:36 +0100
Try the following patch - it should fix the problem with the stream
hanging on large outputs. I don't know about you other problem, though -
maybe you could construct a small example that shows the problem?
/p
---------------------------------------------------------------------------
Index: com/mindbright/ssh2/SSH2Channel.java
===================================================================
RCS file:
/usr/site/share/cvsroot/mindterm/src/com/mindbright/ssh2/SSH2Channel.java,v
retrieving revision 1.12
retrieving revision 1.14
diff -u -r1.12 -r1.14
--- com/mindbright/ssh2/SSH2Channel.java 2003/07/09 12:32:55 1.12
+++ com/mindbright/ssh2/SSH2Channel.java 2003/10/30 09:54:43 1.14
@@ -315,11 +315,11 @@
*/
protected final synchronized void sendClose() {
if(!closeSent) {
+ closeSent = true;
SSH2TransportPDU pdu =
SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_CHANNEL_CLOSE);
pdu.writeInt(peerChanId);
connection.transmit(pdu);
- closeSent = true;
}
checkTermination();
}
Index: com/mindbright/ssh2/SSH2SessionChannel.java
===================================================================
RCS file:
/usr/site/share/cvsroot/mindterm/src/com/mindbright/ssh2/SSH2SessionChannel.java,v
retrieving revision 1.9
retrieving revision 1.11
diff -u -r1.9 -r1.11
--- com/mindbright/ssh2/SSH2SessionChannel.java 2003/07/07 04:59:51 1.9
+++ com/mindbright/ssh2/SSH2SessionChannel.java 2003/11/18 13:11:51 1.11
@@ -52,9 +52,9 @@
protected SSH2SessionChannel(SSH2Connection connection) {
super(SSH2Connection.CH_TYPE_SESSION, connection);
- this.rxInitWinSz = 16384;
- this.rxCurrWinSz = 16384;
- this.rxMaxPktSz = 4096;
+ this.rxInitWinSz = 16*1024;
+ this.rxCurrWinSz = 16*1024;
+ this.rxMaxPktSz = 4*1024;
this.started = false;
this.exited = false;
this.blocking = true;
@@ -287,23 +287,26 @@
connection.getLog().error("SSH2SessionChannel", "extData",
"extended data of unknown type: " + type);
} else {
- try {
+ try {
+
int len = pdu.readInt();
byte[] data = pdu.getData();
int off = pdu.getRPos();
- if(stderrW != null) {
- stderrW.write(data, off, len);
- } else {
- connection.getLog().debug("SSH2SessionChannel",
- "session " + "(ch. #" + channelId +
- ") stderr : " +
- new String(data, off, len));
- }
- } catch (IOException e) {
- connection.getLog().error("SSH2SessionChannel", "extData",
- "error writing to stderr: " +
- e.getMessage());
- }
+ rxCounter += len;
+ if(stderrW != null) {
+ stderrW.write(data, off, len);
+ } else {
+ connection.getLog().debug("SSH2SessionChannel",
+ "session " + "(ch. #" + channelId +
+ ") stderr : " +
+ new String(data, off, len));
+ }
+ checkRxWindowSize(len);
+ } catch (IOException e) {
+ connection.getLog().error("SSH2SessionChannel", "extData",
+ "error writing to stderr: " +
+ e.getMessage());
+ }
}
}
Index: com/mindbright/ssh2/SSH2StreamChannel.java
===================================================================
RCS file:
/usr/site/share/cvsroot/mindterm/src/com/mindbright/ssh2/SSH2StreamChannel.java,v
retrieving revision 1.10
retrieving revision 1.13
diff -u -r1.10 -r1.13
--- com/mindbright/ssh2/SSH2StreamChannel.java 2003/07/09 12:32:55 1.10
+++ com/mindbright/ssh2/SSH2StreamChannel.java 2003/11/18 13:11:51 1.13
@@ -94,7 +94,7 @@
int maxSz = 0;
int rcvSz = 0;
boolean interrupted = false;
- while(!eofSent) {
+ while(!eofSent && !closeSent) {
pdu =
SSH2TransportPDU.createOutgoingPacket(SSH2.MSG_CHANNEL_DATA,
txMaxPktSz + 256);
@@ -102,15 +102,15 @@
maxSz = checkTxWindowSize(rcvSz);
do {
try {
- rcvSz = in.read(pdu.data, pdu.wPos + 4, maxSz);
- interrupted = false;
+ rcvSz = in.read(pdu.data, pdu.wPos + 4, maxSz);
+ interrupted = false;
} catch (InterruptedIOException e) {
- interrupted = true;
+ interrupted = true;
}
} while (interrupted);
if(rcvSz == -1) {
sendEOF();
- } else {
+ } else if (!eofSent && !closeSent) {
pdu.writeInt(rcvSz);
pdu.wPos += rcvSz;
txCounter += rcvSz;
@@ -205,7 +205,7 @@
return dataSz;
}
- private final void checkRxWindowSize(int len) {
+ protected final void checkRxWindowSize(int len) {
rxCurrWinSz -= len;
if(rxCurrWinSz < 0) {
connection.fatalDisconnect(SSH2.DISCONNECT_PROTOCOL_ERROR,
---------------------------------------------------------------------------
Matthew White wrote:
> Hi,
>
>
>
> I have been trying to figure out a few problems relating to
> the RemoteShellScript example code. I have written an application which
> directly calls the run method of RemoteShellScript, and I have run into
> at least 2 nasty bugs regarding synchronization. The first bug that I
> encountered was when a large amount of output was received from the
> command that I was executing. After a certain number of messages, output
> would hang, and so would the code. I managed to work around this by
> preventing the code from producing the large amount of output (an error
> was causing the output). Now, I am encountering a situation where
> somehow either the end marker is received out of sequence, or it is not
> received at all (I can't tell which), and, as a result, the application
> hangs. It is odd because I have made MANY successful calls prior to this
> problematic one with no problems, and I have even made the exact same
> call once previously on the machine. Any idea what could be happening or
> how I can fix it?
>
>
>
> Thanks in advance,
>
> Matt
>
>