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

When using XMLin() (from the XML::Simple module) and a $SIG{__DIE__} handler has been assigned, a symbolic reference error is thrown from XML::Parser::Expat. This seems to be specific to the $SIG{__DIE__} handler, as no other signal handlers seem to be affected. What's more, even though the error is thrown XMLin() still does it's magic and returns the expected hash ref.
use XML::Simple; use Data::Dumper; use strict; # note - added exit(1) to keep things simple $SIG{__DIE__} = sub { print "$_[0]"; exit(1) }; my $xml_str = <<XML; <tag1> <tag2 attr1="foo" /> </tag1> XML my $ret = XMLin($xml_str); print Dumper($ret); __output__ Can't use string ("<tag1> <tag2 attr1="foo" /> </t") as a symbol ref while "strict refs" in use at /usr/lib/p +erl5/site_perl/5.6.0/i386-linux//XML/Parser/Expat.pm line 456.
Now, exactly the same code with the $SIG{__DIE__} line commented out produces the expected
$VAR1 = { 'tag2' => { 'attr1' => 'foo' } };
I've tested this code with perl 5.6.0 and 5.6.1 using the latest versions of both XML::Simple and XML::Parser on Linux and Solaris.
If anyone could point out the error in my, or XML::Simple's madness I'd be a happy monk :-)

broquaint

Replies are listed 'Best First'.
Re: XML::Simple conflicts with $SIG{__DIE__}
by perrin (Chancellor) on Apr 17, 2002 at 19:20 UTC
    Um, don't do that. Using a __DIE__ handler totally screws any exception handling (with eval blocks) inside the modules you use. One of the modules you're using must be trying to manage errors with exceptions, and you're breaking it by setting a global __DIE__ handler.
      Or perhaps more properly, any $SIG{__DIE__} handler you install should only ever be used to augment the exception and re-throw it. Anything else completely breaks perl's exception handling mechanism. Here's a working (and useful) example of a good $SIG{__DIE__} handler:
      local $SIG{__DIE__} = sub { my $err = shift; if (ref($err)) { die $err; } else { throw Exception::Unknown (error => $err); } };
      Implementation of the Exception::Unknown class is left as an exercise. Also note the use of local - so that if we're running under something like mod_perl we don't screw up everyone elses handler that might not want this effect.
      All is clear, many thanks perrin!

      The problem is that XML::Parser::Expat does something which it is fully aware is potentially dubious, which is why it is within an eval(). Now normally die() would just set $@ and all would be well, but the custom $SIG{__DIE__} handler was printing out the error XML::Parser::Expat wanted kept quiet, which was the cause of my confusion.

      Here's a *very* simplified version of what was going on

      use strict; $SIG{__DIE__} = sub { print "something went wrong - $_[0]\n" }; eval { my $lexvar = *{"a string"}{IO}; }; # exceptions, shmexcetpions undef $@;
      So while any potential error was intentionally ignored, the custom $SIG{__DIE__} handler was announcing this FUD to the world.

      broquaint