Ticket #55 (closed defect)

Opened 10 years ago

Last modified 8 years ago

non-blocking, normal and stderr stream read bug

Reported by: apjenkins Owned by: bagder
Priority: normal Milestone:
Component: misc Version:
Keywords: Cc: apjenkins, bagder
Blocked By: Blocks:

Description

I have found a bug in libssh2 0.18, where if I have a channel in non-blocking mode and I alternate reading from the standard and error streams of the channel, then no data is ever read; that is channel_read_ex always returns LIBSSH2_ERROR_EAGAIN, even though the remote process is sending data.

Basically, if you have a channel in non-blocking mode, then if you have code like this:

while (stillSomeDataToRead) {

read from stderr stream
nRead = libssh2_channel_read_stderr(

channel, buf, bufsize);

check for errors, handle input

read from std
nRead = libssh2_channel_read(

channel, buf, bufsize);

check for errors, handle input

}

then it often is the case that the channel_reads just keep returning LIBSSH2_ERROR_EAGAIN (-37) forever. If I comment out the libssh2_channel_read_stderr statement, then it does eventually read data from the channel's stdout stream. So it seems that somehow, calling libssh2_channel_read_stderr prevents libssh2_channel_read from ever receiving any data, even though channel_read_stderr always just returns EAGAIN.

I have attached a program which demonstrates the bug. I have tried this on an i386 Linux machine, and an Intel Mac running Leopard, and the bug occurs in both cases. Occasionally the program works correctly so you may need to run it several times to see the problem. If the program works correctly, then it will output

...
channel_read err returned -37
channel_read returned -37
channel_read err returned -37
channel_read returned -37
channel_read err returned -37
channel_read returned 4096

If the failure occurs, then the "returned 4096" line never comes, and the reads just keep returning -37 forever.

Run the program as

./libssh2hang2 YOUPASSWORD

The program will try to establish a connection to the localhost and log in using password auth. Pass your password as the first cmdline argument. It will then exec the "yes" command, which just outputs an endless stream of characters, put the channel into non-blocking mode, and then keep reading until it's read at least 4096 bytes. If you disable the libssh2_channel_read_stderr statement, then it always works.

Please let me know if you need any more information.

Attachments

libssh2hang2.c (2.5 KB) - added by apjenkins 10 years ago.
Program which demonstrates the bug

Download all attachments as: .zip

Change History

Changed 10 years ago by apjenkins

Program which demonstrates the bug

comment:1 Changed 9 years ago by apjenkins

A workaround for this problem seems to be to use libssh2_poll to wait for there to be std or extended data on a channel, and only call libssh2_channel_read_ex on a channel stream if libssh2_poll indicates there is data to be read.

comment:2 Changed 8 years ago by bagder

Does this still happen with version 1.1?

comment:3 Changed 8 years ago by apjenkins

I just tried my test program with version libssh2 1.1 on OS X 10.5.6, and the bug seems to be fixed. Thank you.

comment:4 Changed 8 years ago by bagder

Thanks for telling, case is closed!

Note: See TracTickets for help on using tickets.