Time::Format::time with $SIG{__DIE__} problem

M

Mark

When I added a $SIG{__DIE__} handler to code that uses
$Time::Format::time{}, the sig die handler code is called. I believe
this is happening during the evaluation of $Time::Format::time{}.
Without a $SIG{__DIE__} handler defined the code runs to completion.
Here is some code that illustrates the issue on my Windows XP
workstation.

Is there something I am doing wrong that is causing the sig die to
occur?

use strict;
use warnings;
use Time::Format;

$| = 1;

# Comment out next line for alternate case
$SIG{'__DIE__'} = sub {print("I'm dying.... Reason:
$_[0]\n");exit(1);};

logit("debug output\n");
print "Alive and well after calling logit.\n";
exit;

sub logit {
print $Time::Format::time{'yyyymmdd:hh:mm:ss '}, $_[0];
}

__END__

Ouput for case with sig die handler specified:
I'm dying.... Reason: Can't locate I18N/Langinfo.pm in @INC (@INC
contains: D:/Perl/site/lib D:/Perl/lib .) at (eval 1) line 31, <DATA>
line 1.

Ouput for case with no sig die handler specified:
20100928:13:58:45 debug output
Alive and well after calling logit.
 
I

Ilya Zakharevich

$SIG{'__DIE__'} = sub {print("I'm dying.... Reason:
$_[0]\n");exit(1);};

__DIE__ handlers should check $^S. Is not it LOUDLY documented?

Hope this helps,
Ilya
 
M

Mark

__DIE__ handlers should check $^S. Is not it LOUDLY documented?

I could not find anything in perlipc or perlvar about using $^S. I
could only find it's possible values documented in perlipc.

Perhaps someone would be kind enough to suggest a better place to
look?

I tried adding a check for $^S in the handler. It's value is 0 when
the handler is called. If I understand the docs correctly,
this means that the he handler is not being called due to an issue
with parsing code.

I am at a loss as to how I can use $^S to properly deal with handling
the sig die calls or what is causing the call to occur.
 
C

C.DeRykus

I could not find anything in perlipc or perlvar about using $^S. I
could only find it's possible values documented in perlipc.

Perhaps someone would be kind enough to suggest a better place to
look?

I tried adding a check for $^S in the handler.  It's value is 0 when
the handler is called.  If I understand the docs correctly,
this means that the he handler is not being called due to an issue
with parsing code.

I am at a loss as to how I can use $^S to properly deal with handling
the sig die calls or what is causing the call to occur.

Hm, I see $^S set to 1 in the handler which
indicates the interpreter is executing an eval.
This workaround appears to make the message
go away but I'm not sure if it's advisable:

$SIG{'__DIE__'} =
sub { return if $^S; # ignore if eval
print("I'm dying.... Reason: $_[0]\n");
exit(1);
};

[ calling logit('') before the handler is seen
seems to work too. ]
 
M

Mark

Hm, I see $^S set to 1 in the handler which
indicates the interpreter is executing an eval.
This workaround appears to make the message
go away but I'm not sure if it's advisable:

$SIG{'__DIE__'} =
    sub { return if $^S;   # ignore if eval
          print("I'm dying.... Reason: $_[0]\n");
          exit(1);
        };

Yes. That works for me too. I erred when I reported the value of $^S
was 0.
return if $^S; # ignore if eval

I am thinking the following might be better:

return() unless defined $^S and $^S == 0; # ignore unless program exit

Thank you Charles.
 
K

Keith Thompson

Mark said:
I could not find anything in perlipc or perlvar about using $^S. I
could only find it's possible values documented in perlipc.

Perhaps someone would be kind enough to suggest a better place to
look?

See the end of "perldoc -f die".

See also the "%SIG" section of "perldoc perlvar", and the BUGS section
at the very end:

Having to even think about the $^S variable in your exception
handlers is simply wrong. $SIG{__DIE__} as currently
implemented invites grievous and difficult to track down
errors. Avoid it and use an "END{}" or CORE::GLOBAL::die
override instead.

[...]
 
S

sln

I am thinking the following might be better:

return() unless defined $^S and $^S == 0; # ignore unless program exit

unless defined $^S and $^S == 0 will will be true if:
$^S < 0 || undef || $^S > 0

if $^S will will be true if:
$^S < 0 || $^S > 0

Is that what you want?

-sln
 
M

Mark

unless defined $^S and $^S == 0 will will be true if:
 $^S < 0 || undef || $^S > 0

if $^S will will be true if:
 $^S < 0 || $^S > 0

Is that what you want?

I don't think so, but I'm in a bit over my head here.

According to perlvar:

$^S State
--------- -------------------
undef Parsing module/eval
true (1) Executing an eval
false (0) Otherwise

So I think I should return immediately for cases where $^S is undef as
well as equal to 1 as I only want to deal with abnormal code
termination, for instance due to a call to die.

"perldoc -f die" suggests putting "die @_ if $^S;" as the first line
of the sig die handler. But that wouldn't
handle the case where the handler was called when "parsing module/
eval". I have never seen this happen but I
feel that handling this case as well would be prudent.
 
I

Ilya Zakharevich

$^S State
--------- -------------------
undef Parsing module/eval
true (1) Executing an eval
false (0) Otherwise

So I think I should return immediately for cases where $^S is undef as
well as equal to 1 as I only want to deal with abnormal code
termination, for instance due to a call to die.

"perldoc -f die" suggests putting "die @_ if $^S;" as the first line
of the sig die handler. But that wouldn't
handle the case where the handler was called when "parsing module/
eval". I have never seen this happen but I
feel that handling this case as well would be prudent.

The usual way to report parse errors is to call __WARN__, then
continue parsing (to report as many parse errors as possible), then
report a final parse error.

perl -wle "sub v {defined $^S ? $^S : q(undef)};
$SIG{__WARN__} = sub {my $v = v; print qq(in WARN($v): @_\n)};
$SIG{__DIE__} = sub {my $v = v; print qq(in DIE($v): @_\n)};
eval q(s//)"
in DIE(undef): Substitution replacement not terminated at (eval 1) line 1.

Ilya
 
I

Ilya Zakharevich

See also the "%SIG" section of "perldoc perlvar", and the BUGS section
at the very end:

Having to even think about the $^S variable in your exception
handlers is simply wrong. $SIG{__DIE__} as currently
implemented invites grievous and difficult to track down
errors. Avoid it and use an "END{}" or CORE::GLOBAL::die
override instead.

IMO, tchrist was too opinionated. There WAS a problem; it was solved
by introduction of $^S. Case closed.

(But I'm, of course, biased to the merits of $^S. ;-)

Yours,
Ilya
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top