Subject: Re: Hang in libssh2_sftp_readdir

Re: Hang in libssh2_sftp_readdir

From: Mike Taylor <mike_at_codeshorts.ca>
Date: Wed, 29 Jul 2009 14:04:42 -0400

Hey guys,

Since I can easily reproduce the bug I sat down and tried to get some
more information. I'm not very familiar with the internal workings of
libssh2 yet (because it has worked so well that I haven't had to up
until now:-) But, I'll do my best to shed some light on this.

So, the basics of what happens is that, when things are working
properly.

When I call libssh2_sftp_readdir, it seems to read several large
blocks, but blocks that are smaller than the limit. Since the blocks
are smaller than the limit, EAGAIN is returned from
_libssh2_transport_read.

When I apply the patch that short circuits the loop, this causes a
single call to _libssh2_transport_read that returns the first block of
data with a return code of 0 instead of EAGAIN. Then, things hang
with this stack trace:

#1 0x00070c77 in _libssh2_wait_socket at session.c:520
#2 0x000601dc in libssh2_channel_read_ex at channel.c:1943
#3 0x00072fce in sftp_packet_read at sftp.c:177
#4 0x00073564 in sftp_packet_requirev at sftp.c:374
#5 0x000757d1 in sftp_readdir at sftp.c:1327
#6 0x00075b51 in libssh2_sftp_readdir_ex at sftp.c:1413

I put in some of my own debug statements at key points so that I could
get a feel for what is happening.

I hope this helps. I've got some other matters to attend to, but I'm
happy to dig more later if it will help.

/\/\ike

**BAD**

Here _libssh2_transport_read returns 0 after the first time and things
hang:

2009-07-29 10:00:25.020 Briefcase[12565:5d77] Begin readDirectory
begin libssh2_sftp_readdir_ex
begin _libssh2_transport_read
end _libssh2_transport_read(PACKET_EAGAIN) 2
begin _libssh2_transport_read
end _libssh2_transport_read(PACKET_EAGAIN) 2
begin _libssh2_transport_read
   _libssh2_transport_read(): short circuit (set loop to 0)
   _libssh2_transport_read(): read 1440
end _libssh2_transport_read(0)

- hangs here -

**GOOD**

Here _libssh2_transport_read returns PACKET_EAGAIN and all of the
data from the directory is read before libssh2_sftp_readdir_ex returns.

2009-07-29 10:02:10.758 Briefcase[12603:5183] Begin readDirectory
begin libssh2_sftp_readdir_ex
begin _libssh2_transport_read
end _libssh2_transport_read(PACKET_EAGAIN) 2
begin _libssh2_transport_read
end _libssh2_transport_read(PACKET_EAGAIN) 2
begin _libssh2_transport_read
   _libssh2_transport_read(): read 1440 (limit 16384)
end _libssh2_transport_read(PACKET_EAGAIN) 2
begin _libssh2_transport_read
   _libssh2_transport_read(): read 1440 (limit 16384)
end _libssh2_transport_read(PACKET_EAGAIN) 2
begin _libssh2_transport_read
   _libssh2_transport_read(): read 2084 (limit 16384)
end _libssh2_transport_read(94)
begin _libssh2_transport_read
end _libssh2_transport_read(PACKET_EAGAIN) 2
begin _libssh2_transport_read
end _libssh2_transport_read(PACKET_EAGAIN) 2
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
2009-07-29 10:02:11.804 Briefcase[12603:5183] End readDirectory
begin _libssh2_transport_read
end _libssh2_transport_read(PACKET_EAGAIN) 2
begin _libssh2_transport_read
   _libssh2_transport_read(): read 88 (limit 16384)
end _libssh2_transport_read(93)
begin _libssh2_transport_read
end _libssh2_transport_read(99)
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin _libssh2_transport_read
end _libssh2_transport_read(PACKET_EAGAIN) 2
begin _libssh2_transport_read
   _libssh2_transport_read(): read 192 (limit 16384)
end _libssh2_transport_read(94)
begin _libssh2_transport_read
end _libssh2_transport_read(96)
begin _libssh2_transport_read
end _libssh2_transport_read(98)
begin _libssh2_transport_read
end _libssh2_transport_read(97)
begin _libssh2_transport_read
end _libssh2_transport_read(PACKET_EAGAIN) 2
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin _libssh2_transport_read
end _libssh2_transport_read(PACKET_EAGAIN) 2
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
end libssh2_sftp_readdir_ex
begin libssh2_sftp_readdir_ex
begin _libssh2_transport_read
end _libssh2_transport_read(PACKET_EAGAIN) 2
begin _libssh2_transport_read
end _libssh2_transport_read(PACKET_EAGAIN) 2

_______________________________________________
libssh2-devel http://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel
Received on 2009-07-29