Subject: | Net::SSH2::Channel objects not getting destroyed |
Bug report for Net::SSH2 0.07 running under perl 5.8.6 (Fedora Core 4)
I am using Net::SSH2 as part of a persistent daemon. My issue is that
::Channel objects (including those that are implicitly created by
scp_get) are not getting destroyed, even though they are leaving
scope. This prevents the main Net::SSH2 object from getting destroyed
when it goes out of scope, which causes both a memory leak and a
socket descriptor leak. After a few hours of running, our process fd
space looks like this:
total 284
lrwx------ 1 64 Apr 7 13:43 0 -> /dev/pts/2
lrwx------ 1 64 Apr 7 13:43 1 -> /dev/pts/2
lrwx------ 1 64 Apr 7 13:43 10 -> socket:[23023727]
lrwx------ 1 64 Apr 7 13:43 100 -> socket:[25941479]
lrwx------ 1 64 Apr 7 13:43 101 -> socket:[25942954]
lrwx------ 1 64 Apr 7 13:43 102 -> socket:[25943607]
lrwx------ 1 64 Apr 7 13:43 103 -> socket:[25945043]
lrwx------ 1 64 Apr 7 13:43 104 -> socket:[25945575]
lrwx------ 1 64 Apr 7 13:43 105 -> socket:[25946014]
lrwx------ 1 64 Apr 7 13:43 106 -> socket:[25947262]
lrwx------ 1 64 Apr 7 13:43 107 -> socket:[25947851]
lrwx------ 1 64 Apr 7 13:43 108 -> socket:[25949223]
lrwx------ 1 64 Apr 7 13:43 109 -> socket:[25950742]
lrwx------ 1 64 Apr 7 13:43 11 -> socket:[23024789]
lrwx------ 1 64 Apr 7 13:43 110 -> socket:[25951710]
lrwx------ 1 64 Apr 7 13:43 111 -> socket:[25952922]
lrwx------ 1 64 Apr 7 13:43 112 -> socket:[25953707]
lrwx------ 1 64 Apr 7 13:43 113 -> socket:[25955436]
lrwx------ 1 64 Apr 7 13:43 114 -> socket:[25957008]
lrwx------ 1 64 Apr 7 13:43 115 -> socket:[25957766]
lrwx------ 1 64 Apr 7 13:43 116 -> socket:[25958984]
lrwx------ 1 64 Apr 7 13:43 117 -> socket:[25993099]
...and so on. Eventually the process either consumes all memory or
hits the system fd limit and aborts.
Here is some debug output from two different sessions. The first one
is looking for files to copy (using SFTP stat) but doesn't find any.
At the end the Net::SSH2 object is destroyed.
[debug] start ssh session
libssh2_sftp_init(ss->session) -> 0xa7cc6c0
hv_from_attrs: attrs->flags = 15
hv_from_attrs: attrs->flags = 15
libssh2_sftp_open_ex(sf->sftp, (char*)pv_file, len_file, l_flags,
mode, 0) -> 0x0
libssh2_sftp_open_ex(sf->sftp, (char*)pv_file, len_file, l_flags,
mode, 0) -> 0x0
libssh2_sftp_open_ex(sf->sftp, (char*)pv_file, len_file, l_flags,
mode, 0) -> 0x0
libssh2_sftp_open_ex(sf->sftp, (char*)pv_file, len_file, l_flags,
mode, 0) -> 0x0
Net::SSH2::SFTP::DESTROY
Net::SSH2::SFTP::DESTROY freeing session
Net::SSH2::DESTROY
[debug] end ssh session
The second session does find files it needs to pull down, and calls
scp_get to copy them. Notice the destructor is NOT getting called at
the end.
[debug] start ssh session
libssh2_sftp_init(ss->session) -> 0xab1d610
libssh2_sftp_open_ex(sf->sftp, (char*)pv_file, len_file, l_flags,
mode, 0) -> 0xa7cdc88
libssh2_scp_recv(ss->session, path, &st) -> 0xcc0aa88
Net::SSH2::Channel::read(size = 1736739, ext = 0)
- read 1736739 total
Net::SSH2::Channel::read(size = 1, ext = 0)
- read 1 bytes
- read 1 total
libssh2_sftp_open_ex(sf->sftp, (char*)pv_file, len_file, l_flags,
mode, 0) -> 0xc403f38
libssh2_scp_recv(ss->session, path, &st) -> 0xb50bae8
Net::SSH2::Channel::read(size = 826046, ext = 0)
- read 826046 total
Net::SSH2::Channel::read(size = 1, ext = 0)
- read 1 bytes
- read 1 total
libssh2_sftp_open_ex(sf->sftp, (char*)pv_file, len_file, l_flags,
mode, 0) -> 0xa7d2b60
libssh2_scp_recv(ss->session, path, &st) -> 0xafb63c8
Net::SSH2::Channel::read(size = 28231, ext = 0)
- read 28231 total
Net::SSH2::Channel::read(size = 1, ext = 0)
- read 1 bytes
- read 1 total
[debug] end ssh session
We have another process similar to this one that opens a shell
channel, which suffers from the same problem. Even when the channel
object goes out of scope in our program, its destructor is not called,
and so the Net::SSH2 object is not destroyed either.
The test script itself exhibits this same behavior, if the full
interactive test is run. DESTROY is never called.
I have tried debugging this myself to no avail. I cannot find where the
refcounts are getting erroneously incremented.
I also sent an email on this issue to the ssh-sftp-users-list on 4/7 but
never received a reply. I'm hoping this is a better way to get
someone's attention.