rkitover/net-ssh2 — Issue #4: Net::SSH2 should never free any resources in non-owner process
Author: xaka
Created: 2011-10-29 19:08:07+00:00
State: open

Let's see the following pseudo example:

1. create the session and the channel

2. fork -> exit-from-child -> waitpid (really simple sequence)

3. try to read from the channel - hangs forever

The issue is in DESTROY functions which do free on session and related objects (channels, dirs, ...). The free is not only about free the memory blocks, but also about sending close messages and so on, which causes the server stop any activity. The only workaround to prevent DESTROY to be called from a child process is use POSIX::_exit, but how many developers know about it?

I had the same issue some time ago in a different situation (my own code) and the only solution which i see is keep track the process where an object has been created, and check the process at the destroy time. If it's different - don't call libssh2_*_free. Any allocated memory will be free anyway after child process death - don't need to bother about it.

I have the patch which adds "pid" attribute to SSH2 and SSH2_* structures. It's filled out with a "getpid" result at the construction time and compared with a "getpid" result again at the destroy time. Result different? -> don't call libssh2_*_free for __this__ object. Works very wells and i don't see any new or hidden issues with it. Probably it'll also fix mentioned Segfaults on exit from TODO.

If you're agree with it, i can make a pull request or attach the patch to this issue.