Why does Net::SFTP trigger my die handler when no errors?

Discussion in 'Perl Misc' started by usenet@DavidFilmer.com, Jan 31, 2006.

  1. Guest

    Greetings. Kindly consider, if you please, this trivial sample script
    which illustrates my question:

    #!/usr/bin/perl
    use warnings; use strict;
    use Net::SFTP;

    local $SIG{__DIE__} = sub {
    print "Oh no - I'm dead!\n";
    };

    my ( $host, $user, $password, $local_file, $remote_file ) =
    qw{ myhost myname mypasswrd junk.txt junk2.txt };

    if (my $sftp = Net::SFTP->new($host, (user => $user,
    password => $password,)
    )
    ) {
    $sftp -> put ($local_file, $remote_file)
    || warn $sftp->status();
    }
    print "I'm done - have a nice day.\n";

    __END__

    As you see, I have defined a custom "die" handler. For some reason,
    when I run this script, I get three "die" messages from this handler,
    even though the script successfully does the "put" and cleanly exits
    with the polite message.

    Why is Net::SFTP triggering my die handler when nothing seems to be
    dying?

    Thanks for any insights!

    --
    http://DavidFilmer.com
     
    , Jan 31, 2006
    #1
    1. Advertising

  2. Xicheng Guest

    wrote:
    > Greetings. Kindly consider, if you please, this trivial sample script
    > which illustrates my question:
    > #!/usr/bin/perl
    > use warnings; use strict;
    > use Net::SFTP;
    >
    > local $SIG{__DIE__} = sub {
    > print "Oh no - I'm dead!\n";
    > };
    >
    > my ( $host, $user, $password, $local_file, $remote_file ) =
    > qw{ myhost myname mypasswrd junk.txt junk2.txt };
    >
    > if (my $sftp = Net::SFTP->new($host, (user => $user,
    > password => $password,)
    > )
    > ) {
    > $sftp -> put ($local_file, $remote_file)
    > || warn $sftp->status();
    > }
    > print "I'm done - have a nice day.\n";
    >
    > __END__
    >
    > As you see, I have defined a custom "die" handler. For some reason,
    > when I run this script, I get three "die" messages from this handler,
    > even though the script successfully does the "put" and cleanly exits
    > with the polite message.


    Firstly, I knew nothing about this module, so my suggestions may be not
    useful for you.

    After I checked perldoc about this module, I guess you can take a look
    at the following issues:

    1) in the Net::SFTP->new(%host, %arg), there is a "warn" option in the
    hash %arg, it shows:
    warn: If given a sub ref, the sub is called with $self and any warning
    message; if set to false, warnings are supressed; OTHERWISE they are
    output with 'warn' (default).
    so, you may get a default warning from this line if your failed in
    creating a new instance.

    > Why is Net::SFTP triggering my die handler when nothing seems to be
    > dying?

    2) $sftp->status
    If a low-level protocol error or unexpected local error occurs, we DIE
    with an error message.
    so you may trigger your die handler here(just guess)

    3) another error info may come directly from the "warn" clause..

    IMHO, this module has embedded with independent error handling
    mechanism so you dont have to do them all by yourself.

    Good luck,
    Xicheng
     
    Xicheng, Jan 31, 2006
    #2
    1. Advertising

  3. wrote in news::

    > Greetings. Kindly consider, if you please, this trivial sample script
    > which illustrates my question:
    >
    > #!/usr/bin/perl
    > use warnings; use strict;
    > use Net::SFTP;
    >
    > local $SIG{__DIE__} = sub {
    > print "Oh no - I'm dead!\n";
    > };
    >
    > my ( $host, $user, $password, $local_file, $remote_file ) =
    > qw{ myhost myname mypasswrd junk.txt junk2.txt };
    >
    > if (my $sftp = Net::SFTP->new($host, (user => $user,
    > password => $password,)
    > )
    > ) {
    > $sftp -> put ($local_file, $remote_file)
    > || warn $sftp->status();
    > }
    > print "I'm done - have a nice day.\n";
    >
    > __END__


    Platform and Perl version?

    I am on WinXP SP2 with perl 5.8.7 (815).

    > As you see, I have defined a custom "die" handler. For some reason,
    > when I run this script, I get three "die" messages from this handler,
    > even though the script successfully does the "put" and cleanly exits
    > with the polite message.


    You are lucky then. With debugging turned on, I get:

    D:\Home\asu1\UseNet\clpmisc> sftp.pl
    Aardvark: Reading configuration data D:/Home/asu1/.ssh/config
    Aardvark: Reading configuration data /etc/ssh_config
    Oh no - I'm dead!
    Aardvark: Connecting to xxx.example.com, port 22.
    Aardvark: Remote protocol version 2.0, remote software version OpenSSH_3.8.1p1 FreeBSD-20040419
    Oh no - I'm dead!
    Oh no - I'm dead!
    Oh no - I'm dead!
    Oh no - I'm dead!
    Oh no - I'm dead!
    Oh no - I'm dead!
    Aardvark: Net::SSH::perl Version 1.29, protocol version 2.0.
    Aardvark: No compat match: OpenSSH_3.8.1p1 FreeBSD-20040419.
    Oh no - I'm dead!
    Can't set socket non-blocking: Bad file descriptor at C:/opt/Perl/site/lib/Net/SSH/Perl.pm line 212, <GEN0> line 1.

    > Why is Net::SFTP triggering my die handler when nothing seems to be
    > dying?
    >
    > Thanks for any insights!


    I tried single-stepping through the code (now, that's tedious).

    Math::BigInt::CODE(0x281dd10)((eval 14)[C:/opt/Perl/lib/Math/BigInt.pm:2435]:1):

    1: use Math::BigInt::GMP qw/Math::BigInt::GMP Pari FastCalc Calc/;
    DB<1> s
    main::CODE(0x182e1cc)(sftp.pl:6): print "Oh no - I'm dead!\n";
    DB<1> s
    Oh no - I'm dead!
    main::CODE(0x182e1cc)(sftp.pl:6): print "Oh no - I'm dead!\n";
    DB<1> s
    Oh no - I'm dead!

    ....

    Math::BigInt::CODE(0x28124b4)((eval 15)[C:/opt/Perl/lib/Math/BigInt.pm:2435]:1):

    1: use Math::BigInt::pari qw/Math::BigInt::GMP Math::BigInt::pari FastCalc
    Calc/;
    DB<1> s
    main::CODE(0x182e1cc)(sftp.pl:6): print "Oh no - I'm dead!\n";
    DB<1> s
    Oh no - I'm dead!
    main::CODE(0x182e1cc)(sftp.pl:6): print "Oh no - I'm dead!\n";
    DB<1> T
    $ = main::__ANON__[sftp.pl:7]('Can\'t locate Math/BigInt/Pari.pm in @INC (@INC c
    ontains: C:/opt/Perl/lib C:/opt/Perl/site/lib .) at (eval 15)[C:/opt/Perl/lib/Ma
    th/BigInt.pm:2435] line 1, <GEN0> line 1.^JBEGIN failed--compilation aborted at
    (eval 15)[C:/opt/Perl/lib/Math/BigInt.pm:2435] line 1, <GEN0> line 1.^J') called
    from file `(eval 15)[C:/opt/Perl/lib/Math/BigInt.pm:2435]' line 1

    Hmmm ... I had thought I all that was installed when I installed
    Net::SFTP via ppm.

    I installed Math::BigInt::GMP and Math::BigInt::Fast via ppm,
    Math::BigInt::pari using Makefile.PL, and run into problems compiling
    Math::BigInt::FastCalc (in case anyone knows what the to do, the
    problem is "unresolved external symbol __ftol2"). Anyway, installing
    what I was able to install reduced the number of "I'm dead" messages:

    D:\Home\asu1\UseNet\clpmisc> sftp.pl
    Oh no - I'm dead!
    Oh no - I'm dead!
    Can't set socket non-blocking: Bad file descriptor at C:/opt/Perl/site/lib/Net/S
    SH/Perl.pm line 212, <GEN0> line 1.

    I give up for now.

    Sinan

    --
    A. Sinan Unur <>
    (reverse each component and remove .invalid for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
     
    A. Sinan Unur, Jan 31, 2006
    #3
  4. "A. Sinan Unur" <> wrote in
    news:Xns975BE796DEBDBasu1cornelledu@127.0.0.1:

    > problems compiling Math::BigInt::FastCalc (in case anyone knows
    > what the to do, the problem is "unresolved external symbol __ftol2").


    If anyone is interested, adding /QIfist to CCFLAGS allowed me to compile
    the module, and the module passed all the tests.

    The script still emits "I'm dead" twice though.

    Single-stepping reveals:

    Net::SSH::perl::_current_user(C:/opt/Perl/site/lib/Net/SSH/Perl.pm:99):
    99: eval { $user = scalar getpwuid $> };
    DB<3> s
    main::CODE(0x182e1cc)(sftp.pl:6): print "Oh no - I'm dead!\n";
    DB<3> s
    Oh no - I'm dead!

    and then (after a lot of stepping):

    Net::SSH::perl::_connect(C:/opt/Perl/site/lib/Net/SSH/Perl.pm:212):
    212: defined($sock->blocking(0))
    213: or die "Can't set socket non-blocking: $!";
    DB<17> s
    main::CODE(0x182e1cc)(sftp.pl:6): print "Oh no - I'm dead!\n";
    DB<17> s
    Oh no - I'm dead!
    Can't set socket non-blocking: Bad file descriptor at
    C:/opt/Perl/site/lib/Net/SSH/Perl.pm line 212, <GEN0> line 1.

    Hmmmmm ...

    Sinan
    --
    A. Sinan Unur <>
    (reverse each component and remove .invalid for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
     
    A. Sinan Unur, Jan 31, 2006
    #4
  5. "A. Sinan Unur" <> wrote in
    news:Xns975BED966C7FDasu1cornelledu@127.0.0.1:

    > Net::SSH::perl::_connect(C:/opt/Perl/site/lib/Net/SSH/Perl.pm:212):
    > 212: defined($sock->blocking(0))
    > 213: or die "Can't set socket non-blocking: $!";
    > DB<17> s
    > main::CODE(0x182e1cc)(sftp.pl:6): print "Oh no - I'm dead!\n";
    > DB<17> s
    > Oh no - I'm dead!
    > Can't set socket non-blocking: Bad file descriptor at
    > C:/opt/Perl/site/lib/Net/SSH/Perl.pm line 212, <GEN0> line 1.


    OK. I am now positively talking to myself.

    This is listed as "resolved" at
    http://rt.cpan.org/Public/Bug/Display.html?id=17127

    Anyone know what the resolution is?

    Sinan
    --
    A. Sinan Unur <>
    (reverse each component and remove .invalid for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
     
    A. Sinan Unur, Jan 31, 2006
    #5
  6. Guest

    wrote:
    > Greetings. Kindly consider, if you please, this trivial sample script
    > which illustrates my question:
    >
    > #!/usr/bin/perl
    > use warnings; use strict;
    > use Net::SFTP;
    >
    > local $SIG{__DIE__} = sub {
    > print "Oh no - I'm dead!\n";
    > };


    I think it would be nice, at least for debugging purposes, if you had your
    sub print out the error message it was called with. Then you would know
    what it was.

    ....

    >
    > As you see, I have defined a custom "die" handler. For some reason,
    > when I run this script, I get three "die" messages from this handler,
    > even though the script successfully does the "put" and cleanly exits
    > with the polite message.
    >
    > Why is Net::SFTP triggering my die handler when nothing seems to be
    > dying?


    You should ask Perl that, not us!

    However, from perldoc perlvar:

    Due to an implementation glitch, the $SIG{__DIE__} hook is
    called even inside an eval(). Do not use this to rewrite a
    pending exception in $@, or as a bizarre substitute for
    over- riding CORE::GLOBAL::die(). This strange action at a
    distance may be fixed in a future release so that
    $SIG{__DIE__} is only called if your program is about to
    exit, as was the original intent. Any other use is
    deprecated.

    So it would be my guess that Net::SFTP is dying from inside an eval, as
    part of its normal course of business, and you are intercepting those dies.

    But this lead me to ask a broader question. What are you trying to do, and
    why are you using a SIG die handler, rather than eval{}, to do whatever it
    is you are tyring to do?

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
     
    , Jan 31, 2006
    #6
  7. wrote in news:20060131110941.189$:

    > wrote:
    >> Greetings. Kindly consider, if you please, this trivial sample script
    >> which illustrates my question:
    >>
    >> #!/usr/bin/perl
    >> use warnings; use strict;
    >> use Net::SFTP;
    >>
    >> local $SIG{__DIE__} = sub {
    >> print "Oh no - I'm dead!\n";
    >> };

    >
    > I think it would be nice, at least for debugging purposes, if you had
    > your sub print out the error message it was called with. Then you
    > would know what it was.


    Yeah ... I did it the long hard way ... It was dying in a bunch of
    evals.

    > However, from perldoc perlvar:
    >
    > Due to an implementation glitch, the $SIG{__DIE__} hook
    > is called even inside an eval(). Do not use this to
    > rewrite a pending exception in $@, or as a bizarre
    > substitute for over- riding CORE::GLOBAL::die(). This
    > strange action at a distance may be fixed in a future
    > release so that $SIG{__DIE__} is only called if your
    > program is about to exit, as was the original intent.
    > Any other use is deprecated.


    Oooops ... I missed that and I wasted a lot of time.

    > So it would be my guess that Net::SFTP is dying from inside an eval,


    That is true. In wasting my time on this, I realized that David's script
    does not actually work on my machine because Net::SSH::perl dies:

    > Net::SSH::perl::_connect(C:/opt/Perl/site/lib/Net/SSH/Perl.pm:212):
    > 212: defined($sock->blocking(0))
    > 213: or die "Can't set socket non-blocking: $!";
    > DB<17> s
    > main::CODE(0x182e1cc)(sftp.pl:6): print "Oh no - I'm dead!\n";
    > DB<17> s
    > Oh no - I'm dead!
    > Can't set socket non-blocking: Bad file descriptor at
    > C:/opt/Perl/site/lib/Net/SSH/Perl.pm line 212, <GEN0> line 1.


    This is listed as a resolved bug at
    http://rt.cpan.org/Public/Bug/Display.html?id=17127

    I hate to repeat myself, but I am kind of puzzled. I don't need SFTP
    anytime soon, but does anyone know what the resolution is?

    Sinan
    --
    A. Sinan Unur <>
    (reverse each component and remove .invalid for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
     
    A. Sinan Unur, Jan 31, 2006
    #7
  8. Guest

    wrote:

    > I think it would be nice, at least for debugging purposes, if you had your
    > sub print out the error message it was called with. Then you would know
    > what it was.


    Do you mean $! ? I wasn't sure $! would be reliable here. I actually
    included $! as I was trying to figure out what was going on, and I got
    a bunch of (seemingly) meaningless messages.

    > However, from perldoc perlvar:
    > <snip perldoc>
    > So it would be my guess that Net::SFTP is dying from inside an eval, as
    > part of its normal course of business, and you are intercepting those dies.


    I'm glad you were able to translate that perldoc statement (which I
    struggle to understand, with little success) into something that makes
    sense! Thanks!
    >
    > But this lead me to ask a broader question. What are you trying to do, and
    > why are you using a SIG die handler, rather than eval{}, to do whatever it
    > is you are tyring to do?
    >

    The die handler is designed to catch my own die() calls. I die within
    my script under various dire circumstances, but I want to do some
    housecleaning before I really leave (dispatching final logging methods,
    closing databases cleanly, etc), so I use the handler. Maybe that's not
    the best way to do it...

    I didn't anticipate catching any die()s from Net::SFTP because the docs
    for the module claim it die()s only in under fairly restrictive (and
    unlikely) conditions. Your speculation about the module die()'ng inside
    evals sounds plausable, and will make me re-think my exit strategy for
    exception handling.

    Thanks, Xho (and thanks, Sinan, for your amazing efforts to help also,
    which were apparently thwarted by what seems to be a bug in Net::SSH on
    Windows - but I'm a UN*X weenie).

    --
    http://DavidFilmer.com
     
    , Jan 31, 2006
    #8
  9. Guest

    wrote:
    > wrote:
    >
    > > I think it would be nice, at least for debugging purposes, if you had
    > > your sub print out the error message it was called with. Then you
    > > would know what it was.

    >
    > Do you mean $! ? I wasn't sure $! would be reliable here. I actually
    > included $! as I was trying to figure out what was going on, and I got
    > a bunch of (seemingly) meaningless messages.


    Mind you, I've never actually used SIG die handlers, so this is based on
    the doc, not from experience, But I think what you should print would be
    $_[0].

    The routine indicated by $SIG{__DIE__} is called when a
    fatal exception is about to be thrown. The error message is
    passed as the first argument.



    For example:
    $ perl -le 'local $SIG{__DIE__}=sub {warn qq{Intercepted "$_[0]"}}; \
    eval {die "foo"} '

    results in:

    Intercepted "foo at -e line 2.
    " at -e line 1.

    (OK, so now I guess I have actually used SIG die handlers, so disclaim my
    disclaimer.)

    >
    > > However, from perldoc perlvar:
    > > <snip perldoc>
    > > So it would be my guess that Net::SFTP is dying from inside an eval, as
    > > part of its normal course of business, and you are intercepting those
    > > dies.

    >
    > I'm glad you were able to translate that perldoc statement (which I
    > struggle to understand, with little success) into something that makes
    > sense! Thanks!


    You're welcome.

    > >
    > > But this lead me to ask a broader question. What are you trying to do,
    > > and why are you using a SIG die handler, rather than eval{}, to do
    > > whatever it is you are tyring to do?
    > >

    > The die handler is designed to catch my own die() calls. I die within
    > my script under various dire circumstances, but I want to do some
    > housecleaning before I really leave (dispatching final logging methods,
    > closing databases cleanly, etc),


    I think dispatching final logging methods should probably happen in an END
    block, or perhaps should be automatically triggered when the logging object
    goes out of scope and is destroyed (which happens even if you are exiting
    via die).

    For closing databases cleanly, it is not clear to me that one can generally
    do a better job at handling that than the code already built into DBI does,
    which is triggered when an open db handle goes out of scope or is
    destroyed, for example during clean up after a uncaught "die". There are
    exceptions to every generalization and YMMV, of course.


    > so I use the handler. Maybe that's not
    > the best way to do it...


    I think that:

    {
    local $SIG{__DIE__} = sub { do_something_with_error($_[0]) };
    ## rest of code in block;
    };

    Should usually be functionally equivalent to:

    eval {
    ## rest of code in block;
    };
    if ($@) { do_something_with_error($@); die $@ };

    Except the latter doesn't intercept other peoples dies if those dies are in
    evals of their own, while the former does. (One potential problem is that
    the handler can be a closure upon lexicals in the block, while the if after
    the eval can not.)


    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
     
    , Jan 31, 2006
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Lloyd Sheen

    Die IDE Die

    Lloyd Sheen, Jan 24, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    436
    Natty Gur
    Jan 26, 2004
  2. Lloyd Sheen

    More Die IDE Die

    Lloyd Sheen, Jan 24, 2004, in forum: ASP .Net
    Replies:
    5
    Views:
    453
    Alvin Bruney
    Jan 25, 2004
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,003
    Smokey Grindel
    Dec 2, 2006
  4. MaggotChild

    Net::SFTP Fails, sftp OK

    MaggotChild, Oct 28, 2009, in forum: Perl Misc
    Replies:
    2
    Views:
    983
    C.DeRykus
    Oct 29, 2009
  5. Kevin13
    Replies:
    3
    Views:
    934
    Kevin13
    Dec 1, 2009
Loading...

Share This Page