dagolden / Capture-Tiny

(Perl) Capture STDOUT and STDERR from Perl, XS or external programs
http://search.cpan.org/dist/Capture-Tiny/
39 stars 19 forks source link

tee hangs when running sshutle in daemonized mode #52

Open melezhik opened 7 years ago

melezhik commented 7 years ago

Hi! Here is test story:


$ cat test.bash
/usr/sbin/sshuttle -v -D -r vagrant@127.0.0.1 192.168.0.0/24
echo OK

$ cat test.pl
use Capture::Tiny qw{tee};
tee {
  system("bash test.bash");
};

$ perl test.pl
Starting sshuttle proxy.
Listening on ('127.0.0.1', 12300).
c : connecting to server...
vagrant@127.0.0.1's password:
Connected.
c : connected.
OK
...

... It hangs here 
... So I have to press CTRL+C to finish test.pl script

CTRL + C

$ ps uax|grep sshu
root      7153  0.0  0.0  40524  3476 pts/1    S    22:53   0:00 sudo -p [local sudo] Password:  python /usr/lib/sshuttle/main.py python -v --firewall 12300 0 --syslog
root      7154  0.1  0.2  35148 10088 ?        Ss   22:53   0:00 python /usr/lib/sshuttle/main.py python -v --firewall 12300 0 --syslog
vagrant   7164  0.0  0.1  35524  7700 ?        S    22:53   0:00 python /usr/lib/sshuttle/main.py python -v -D -r vagrant@127.0.0.1 192.168.0.0/24
vagrant   7177  0.0  0.0  12720  2164 pts/1    R+   22:53   0:00 grep sshu

Compare this with when runs test.bash directly:

$ bash test.bash
Starting sshuttle proxy.
Listening on ('127.0.0.1', 12300).
c : connecting to server...
vagrant@127.0.0.1's password:
c : connected.
Connected.
OK
# it finishes here

$ ps uax|grep sshu
vagrant   7205  0.0  0.0  23712  2560 pts/1    S    22:54   0:00 logger -p daemon.notice -t sshuttle
root      7206  0.0  0.0  40524  3468 pts/1    S    22:54   0:00 sudo -p [local sudo] Password:  python /usr/lib/sshuttle/main.py python -v --firewall 12300 0 --syslog
root      7207  0.2  0.2  35148 10216 ?        Ss   22:54   0:00 python /usr/lib/sshuttle/main.py python -v --firewall 12300 0 --syslog
root      7208  0.0  0.0  23712  2392 pts/1    S    22:54   0:00 logger -p daemon.notice -t sshuttle
vagrant   7217  0.0  0.1  35524  7656 ?        S    22:54   0:00 python /usr/lib/sshuttle/main.py python -v -D -r vagrant@127.0.0.1 192.168.0.0/24

Also there is thread started by me at PerlMonks which you may find useful http://perlmonks.org/?node_id=1185749 with regards to this issue.

Sshutle information could be found here - https://github.com/apenwarr/sshuttle , there is no any special about besides it probably demonizes improperly. However this could be considered as example of such a "bad" external programs which Capture::Tiny interacts whit by IPC and which make it hangs ... Anyway probably we need to investigate this more ...

melezhik commented 7 years ago

A further investigation.

Looks like function _keel_tees can't waitpid - https://github.com/dagolden/Capture-Tiny/blob/master/lib/Capture/Tiny.pm#L286 and thus hangs forever :

These are the child (tees) processes can't be waited in parent process:

# invoking in parallel terminal when script hangs:
$ ps uax|grep perl | grep -v watch
vagrant  11078  0.0  0.1  37660  8084 pts/1    S+   10:03   0:00 perl test.pl
vagrant  11079  0.0  0.0  23812  4380 pts/1    S+   10:03   0:00 /home/vagrant/perl5/perlbrew/perls/perl-5.24.1/bin/perl -C0 -e use Fcntl; $SIG{HUP}=sub{exit}; if ( my $fn=shift ) {     sysopen(my $fh, qq{$fn}, O_WRONLY|O_CREAT|O_EXCL) or die $!;     print {$fh} $$;     close $fh; } my $buf; while (sysread(STDIN, $buf, 2048)) {     syswrite(STDOUT, $buf); syswrite(STDERR, $buf); }  /tmp/oVVAM1Ixty
vagrant  11080  0.0  0.0  23812  4336 pts/1    S+   10:03   0:00 /home/vagrant/perl5/perlbrew/perls/perl-5.24.1/bin/perl -C0 -e use Fcntl; $SIG{HUP}=sub{exit}; if ( my $fn=shift ) {     sysopen(my $fh, qq{$fn}, O_WRONLY|O_CREAT|O_EXCL) or die $!;     print {$fh} $$;     close $fh; } my $buf; while (sysread(STDIN, $buf, 2048)) {     syswrite(STDOUT, $buf); syswrite(STDERR, $buf); }  /tmp/fo1UeJaVAo

# or in hierarchy mode:

$ ps fuax | grep perl

vagrant  11078  0.5  0.1  37660  8084 pts/1    S+   10:03   0:00  |           \_ perl test.pl
vagrant  11079  0.0  0.0  23812  4380 pts/1    S+   10:03   0:00  |               \_ /home/vagrant/perl5/perlbrew/perls/perl-5.24.1/bin/perl -C0 -e use Fcntl; $SIG{HUP}=sub{exit}; if ( my $fn=shift ) {     sysopen(my $fh, qq{$fn}, O_WRONLY|O_CREAT|O_EXCL) or die $!;     print {$fh} $$;     close $fh; } my $buf; while (sysread(STDIN, $buf, 2048)) {     syswrite(STDOUT, $buf); syswrite(STDERR, $buf); }  /tmp/oVVAM1Ixty
vagrant  11080  0.0  0.0  23812  4336 pts/1    S+   10:03   0:00  |               \_ /home/vagrant/perl5/perlbrew/perls/perl-5.24.1/bin/perl -C0 -e use Fcntl; $SIG{HUP}=sub{exit}; if ( my $fn=shift ) {     sysopen(my $fh, qq{$fn}, O_WRONLY|O_CREAT|O_EXCL) or die $!;     print {$fh} $$;     close $fh; } my $buf; while (sysread(STDIN, $buf, 2048)) {     syswrite(STDOUT, $buf); syswrite(STDERR, $buf); }  /tmp/fo1UeJaVAo

Killing those tee's processes in parallel console make script finished:

$ kill 11079 11080
melezhik commented 7 years ago

Meanwhile I run cross issue against sshulte - https://github.com/sshuttle/sshuttle/issues/139