in reply to perl crash during global destruction

Your test case can be simplified somewhat further and still crash:

#!/usr/bin/perl use strict; use warnings; package Foo; sub new { my ($class) = @_; return bless {}, $class; } sub DESTROY { Foo->new(); } package main; Foo->new ();

It may even be obvious now why it crashes. No? Well, consider what happens to the instance constructed in the destructor as the destructor cleans up before exiting.

It may be that this is a different issue than the one you are experiencing (I can't tell exactly from your various snippets of code), but it is the problem you describe.

Actually there are a number of issues in your code that look a little Perl 4ish or otherwise sub-optimum.


True laziness is hard work

Replies are listed 'Best First'.
Re^2: perl crash during global destruction
by flipper (Beadle) on Apr 01, 2010 at 09:15 UTC

    Yes I don't think the code I gave was very easy to understand - too many foos!

    The style issues were mostly introduced by me paring down 20,000 lines of code to 40 (and the odd C++ programmer :)

    Your example is not exactly the same as the issue I'm seeing, but your example is much clearer - based on that, the following does not crash:

    package Foo; use strict; use XML::LibXML; use Scalar::Util qw/weaken/; use Data::Dumper; sub DESTROY { my $self=shift; warn "\n$self dtor"; } sub new { warn "\n".__PACKAGE__." xtor"; my $self = {}; bless $self, __PACKAGE__; my $parser = XML::LibXML->new(); my $confdoc = $parser->parse_string('<foo att1="val1"/>'); my $root = $confdoc->documentElement(); my @nodes = $root->findnodes('/*'); for my $n (@nodes){ for my $att ($n->attributes()) { my $foo = $att->nodeName; my ($key, $val) = (lc($att->nodeName), lc($att +->getValue)); warn "$key - $val"; } } warn __PACKAGE__." xtor COMPLETE"; return $self; } package user; sub DESTROY {Foo->new()} bless my $self=[] => __PACKAGE__; my $f=Foo->new();

    but essentially the same code using a Foo.pm and crash.pl does:

    #Foo.pm package Foo; use strict; use XML::LibXML; use Scalar::Util qw/weaken/; use Data::Dumper; sub DESTROY { my $self=shift; warn "\n$self dtor"; } sub new { warn "\n".__PACKAGE__." xtor"; my $self = {}; bless $self, __PACKAGE__; my $parser = XML::LibXML->new(); my $confdoc = $parser->parse_string('<foo att1="val1"/>'); my $root = $confdoc->documentElement(); my @nodes = $root->findnodes('/*'); for my $n (@nodes){ for my $att ($n->attributes()) { my $foo = $att->nodeName; my ($key, $val) = (lc($att->nodeName), lc($att +->getValue)); warn "$key - $val"; } } warn __PACKAGE__." xtor COMPLETE"; return $self; } 1;
    #!/usr/bin/perl #this is crash.pl use Foo; package user; bless ($self=[]) => __PACKAGE__; $f=Foo->new(); sub DESTROY {Foo->new()}
      The code is essentially different. If you insert the two my's missing in crash.pl, you will get the same results.
Re^2: perl crash during global destruction
by lamprecht (Friar) on Mar 31, 2010 at 21:24 UTC

    Oh, and don't construct instances of a class in the class's destructor - that leads to unhappiness.
    He did not do that, did he?

    Cheers, Christoph
      Oh, and don't construct instances of a class in the class's destructor
      He did not do that, did he?

      In the crash case OP presented that is exactly what he did:

      package foo; ... $f=Foo->new(); sub DESTROY {Foo->new()}

      supplies a Foo destructor that creates a new Foo instance. Note that the new destructor replaces the original destructor. It would have been clearer (and the OP may have figured things out for himself) if OP had supplied a stand alone sample script that demonstrated the issue.


      True laziness is hard work