Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Bizarre Proc::Daemon error

by xtpu2 (Acolyte)
on Jun 09, 2014 at 20:32 UTC ( [id://1089323]=perlquestion: print w/replies, xml ) Need Help??

xtpu2 has asked for the wisdom of the Perl Monks concerning the following question:

I'm experiencing a very strange error (strange for my limited experience, anyway) with Proc::Daemon.

I have a perl daemon that fails with the error message:

Can't call method "isa" on unblessed reference at /usr/local/share/perl/5.14.2/Proc/Daemon.pm line 88, <STDIN> line 3.

The line 88 in question from Proc::Daemon is this one:

unless ( ref( $self ) && eval{ $self->isa( 'Proc::Daemon' ) } ) {

It is located in the "Init" subroutine in Proc::Daemon.

The reason that I'm calling this error "bizarre" is because a) Why is the script dying when executing an expression in an eval? Isn't that the whole point of eval? b) This script was working not 2 weeks ago when I was testing it on this same system. During that time there have not been any updates to the Proc::Daemon module or to Perl.

Here is the code that calls Proc::Daemon:

Proc::Daemon::Init({ work_dir => '/tmp', setuid => 'some_uid' });

I do have a custom DIE signal handler (which I thought might be the cause of the error, but if so, I must not understand something about the way evals work). It looks like this:

$SIG{'__DIE__'} = sub{ write_to_log('FATAL! '.join(' ', @_)); die; };

Can anybody shed some light on this thing?

Edited to Add: Further poking around has narrowed the problem down to the setuid parameter for Proc::Daemon::Init. If I remove it, the script runs fine. However, this means the script is running as root and I would like to avoid that. Investigatining further...

Replies are listed 'Best First'.
Re: Bizarre Proc::Daemon error # die-handler
by LanX (Saint) on Jun 10, 2014 at 03:09 UTC
    > a) Why is the script dying when executing an expression in an eval? Isn't that the whole point of eval?

    Your die handler is called from within the block eval and dies like you told him to do. ( update: or maybe not?)

    You might(?)¹ be able to check the caller to avoid dieing in block-eval.

    == Updates

    === From 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 overriding "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.

    === Possible workaround

    ¹) Indeed! As you can see from this test, does caller(1) tell you if the die appeared within an eval .

    So better avoid to die in that case! :)

    (But you should check the whole caller-chain till top-level for the string (eval) )

    use Carp 'cluck'; $SIG{__DIE__}=sub {cluck "called in '",(caller(1))[3],"'\n\n" }; warn "\n---EVALED FATAL\n"; eval { $x=0/0 } or print ">>> $@"; warn "\n---NORMAL FATAL\n"; $x=0/0;

    -->

    ---EVALED FATAL called in '(eval)' at /tmp/tst.pl line 2 main::__ANON__('Illegal division by zero at /tmp/tst.pl line 6.\x{ +a}') called at /tmp/tst.pl line 6 eval {...} called at /tmp/tst.pl line 6 >>> Illegal division by zero at /tmp/tst.pl line 6. ---NORMAL FATAL called in '' at /tmp/tst.pl line 2 main::__ANON__('Illegal division by zero at /tmp/tst.pl line 10.\x +{a}') called at /tmp/tst.pl line 10 Illegal division by zero at /tmp/tst.pl line 10.

    === "may be fixed in a future release"

    Well, I wonder why this was never fixed, if a simple check of caller is sufficient.

    Cheers Rolf

    (addicted to the Perl Programming Language)

      I'm not sure I understand what you're saying here: eval will trap death, even when invoked from a __DIE__ handler:

      % perl -wl local $SIG{__DIE__} = sub { print "in handler (@_)"; die "from handler"; }; eval { die "foo" }; print "eval returned (but knows the error was <$@>)"; __END__ in handler (foo at - line 5. ) eval returned (but knows the error was <from handler at - line 3. >) %

      Hugo

        Strange ...

        ... your snippet runs identically on my machine and I can't reproduce anymore what I saw (!?!)

        Most likely I was wrong about why the OP's program aborts.

        Cheers Rolf

        (addicted to the Perl Programming Language)

Re: Bizarre Proc::Daemon error
by parv (Parson) on Jun 09, 2014 at 22:27 UTC

    At the risk of stating the obvious, the isa() test failed as no Proc::Daemon object was returned by Proc::Daemon::Init() call, which in turn had failed, as OP found later (thanks for the update), while changing of user id.

    ref test might have been added in 0.10 before eval{ isa() }. You may be using a version around there. (Somebody please give me a clue if it is possible to browse older versions code on MetaCPAN (as it is(or was?) possible on search.cpan).)

      > (Somebody please give me a clue if it is possible to browse older versions code on MetaCPAN (as it is(or was?) possible on search.cpan).)

      Yes! Click Release Info then you'll find a drop down named Jump to version.

      HTH! :)

      Cheers Rolf

      (addicted to the Perl Programming Language)

        Thanks much, LanX; ITH.

      I'm using Proc::Daemon version 0.14.

      Do you have any ideas why the uid change is causing this failure? I guess I can always work around this problem by starting the script with sudo user, but I like getting things working the way they're supposed to...

      Actually, I don't even know if sudo user will work. Could it be that the problem is something about the user I'm trying to use?

        Proc::Daemon calls &POSIX::setuid but does not check if the call has failed. Try yourself as root (or, via sudo) the user id change ...

        perl -MPOSIX=setuid -e ' sub show { printf qq[%s: real: %d, effective: %d\n] , $_[0] , $< , $ +> } show( q[current] ); $id = 65535; # Change to the desired value. setuid( $id ) or die qq[cannot change to $id: $!]; show( q[post-change] ) '

        ... also check setuid system call documentation for your system.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1089323]
Approved by boftx
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (6)
As of 2024-04-24 06:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found