Skip Menu |

This queue is for tickets about the Net-OpenSSH CPAN distribution.

Report information
The Basics
Id: 51479
Status: resolved
Worked: 40 min
Priority: 0/
Queue: Net-OpenSSH

People
Owner: salva [...] cpan.org
Requestors: toddr [...] null.net
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.39
Fixed in: (no value)



Subject: Net::OpenSSH not "use forks" safe
Hi, I've found a problem with Net::OpenSSH working in conjunction with use forks. To reproduce, run the test attached to this case, first setting the string on line 52 in the test to a valid user@host. The problem seems to stem from line 392 inside the subroutine _kill_master when $sig == $TERM. Prior to this, die works as expected. Afterwards, die starts misbehaving in that forked process. Eval calls come back with $@ set as an empty string when a die event happens. I'm not really following what's going on in this section of the code, so I can't really suggest a fix. Any ideas how I might get this working? Thanks,
Subject: forks.t
#!/usr/local/bin/perl -w use forks; use forks::shared; use strict; use Test::More; my $dollar_at : shared; my $thr; my $obj; #== Eval/die from sub inside object with OpenSSH === $dollar_at = undef; $obj = open_ssh_test->new(); isa_ok($obj, "open_ssh_test"); $thr = threads->create({'exit' => 'thread_only'}, sub { eval { $obj->connect(); $obj->die_from_object; }; $dollar_at = $@; }); $thr->join(); like($dollar_at, qr/^Failure_message/, "\$\@ behaves fine in calls to Net::OpenSSH->new"); # Prove the issue is related to Net::OpenSSH by calling a sub without it; $dollar_at = undef; $thr = threads->create( sub { eval { $obj->die_from_object; }; $dollar_at = $@; }); $thr->join(); like($dollar_at, qr/^Failure_message/, "\$\@ behaves fine with object calls without ssh calls"); done_testing(); package open_ssh_test; use Net::OpenSSH; sub new { my $class = shift; my $self = {}; return bless($self, $class) } sub connect { my $self = shift; my $ssh = Net::OpenSSH->new('user@host'); die("Failure_message"); $self->{ssh} = $ssh; } sub die_from_object { die("Failure_message"); } 1;
A closer look and a simpler example shows that this is a problem with the DESTROY call IF it's made inside an eval and forks has been required Please ignore the first test. It's unnecessarily complicated.
#!/usr/local/bin/perl -w use strict; use Test::More; use Net::OpenSSH; my $login = 'root@esxi'; eval { my $ssh = Net::OpenSSH->new($login); die("Failure_message"); }; like($@, qr/^Failure_message/, "\$\@ behaves without 'require forks' even when \$ssh->DESTROY is called inside eval"); require forks; eval { my $ssh = Net::OpenSSH->new($login); die("Failure_message"); }; like($@, qr/^Failure_message/, "\$\@ behaves with 'require forks' and \$ssh->DESTROY called inside eval"); # eval still works. only broke in the one case above. eval { die("Failure_message"); }; like($@, qr/^Failure_message/, "\$\@ behaves in simple example"); # die even works as long as DESTROY isn't called. my $ssh = Net::OpenSSH->new($login); eval { die("Failure_message"); }; like($@, qr/^Failure_message/, "\$\@ still behaves since \$ssh->DESTROY wasn't called inside eval this time"); done_testing(); exit;
Solved in version 0.40 now available from CPAN Thank you for reporting it!