We have noticed an issue with jline3's "Less" implementation in combination with Apache MINA SSHD resulting in an infinite loop, when forcibly terminating a SSH session (i.e. closing the terminal window) while Less is running.
Reproducing the Issue
The following snippet allows to reproduce the issue. Once the SSH sessions is established and you are seeing the Less screen, forcibly terminate the session by closing the terminal window. The thread handling the ssh connection will then begin to burn CPU cycles entering an infinite loop.
Versions:
jLine3 3.10.0
Apache SSHD 2.0.0
SshServer sshServer = SshServer.setUpDefaultServer();
sshServer.setKeyPairProvider(new SimpleGeneratorHostKeyProvider());
sshServer.setPasswordAuthenticator((username, password, session) -> true);
sshServer.setShellFactory(new ShellFactoryImpl((x)-> {
Less less = new Less(x.getTerminal());
try {
less.run(new Source() {
@Override
public String getName() {
return "Test File";
}
@Override
public InputStream read() throws IOException {
return new ByteArrayInputStream("Oh my god, Becky. \n\n Look at that InputStream.".getBytes());
}
});
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}));
sshServer.setHost("127.0.0.1");
sshServer.setPort(2223);
sshServer.start();
Thread.sleep(60*1000);
We have extracted the following stack trace of the thread burning the cycles.
"Thread-2@2917" daemon prio=5 tid=0x16 nid=NA runnable
java.lang.Thread.State: RUNNABLE
at org.apache.sshd.common.channel.ChannelOutputStream.flush(ChannelOutputStream.java:174)
- locked <0xbf4> (a org.apache.sshd.common.channel.ChannelOutputStream)
at org.jline.terminal.impl.LineDisciplineTerminal$FilteringOutputStream.flush(LineDisciplineTerminal.java:301)
at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:318)
at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:153)
- locked <0xbf7> (a java.io.OutputStreamWriter)
at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:254)
at java.io.PrintWriter.flush(PrintWriter.java:396)
at org.jline.terminal.impl.AbstractTerminal.flush(AbstractTerminal.java:159)
at org.jline.utils.Display.update(Display.java:331)
at org.jline.utils.Display.update(Display.java:99)
at org.jline.builtins.Less.display(Less.java:634)
- locked <0xbfc> (a org.jline.builtins.Less)
at org.jline.builtins.Less.run(Less.java:384)
at org.jline.builtins.Less.run(Less.java:109)
at a.b.c.JlineIssue.lambda$main$1(JlineIssue.java:32)
at a.b.c.JlineIssue$$Lambda$79.116734858.accept(Unknown Source:-1)
at org.jline.builtins.ssh.ShellFactoryImpl$ShellImpl.run(ShellFactoryImpl.java:225)
at org.jline.builtins.ssh.ShellFactoryImpl$ShellImpl.lambda$start$0(ShellFactoryImpl.java:107)
at org.jline.builtins.ssh.ShellFactoryImpl$ShellImpl$$Lambda$124.2010899121.run(Unknown Source:-1)
at java.lang.Thread.run(Thread.java:834)
I've tried running the demo with ssh, setting up the server, connecting with a native ssh client, running less, killing -9 the client. This does not seem to lead to the problem you describe.
Description
We have noticed an issue with jline3's "Less" implementation in combination with Apache MINA SSHD resulting in an infinite loop, when forcibly terminating a SSH session (i.e. closing the terminal window) while Less is running.
Reproducing the Issue
The following snippet allows to reproduce the issue. Once the SSH sessions is established and you are seeing the Less screen, forcibly terminate the session by closing the terminal window. The thread handling the ssh connection will then begin to burn CPU cycles entering an infinite loop.
Versions: jLine3 3.10.0 Apache SSHD 2.0.0
We have extracted the following stack trace of the thread burning the cycles.