CC: | mst [...] shadowcat.co.uk, ether [...] cpan.org |
Subject: | Constructing a stacktrace within a DESTROY callchain aborts garbage collection, rerunning the destructor at a later point |
Contrived example - note GlobalDestruction is only invoked here for brevity, it is completely possible to have the same issue within normal runtime.
~$ perl -MDevel::StackTrace -e '
sub DESTROY { warn "calling destructor and doing foo"; main::foo() };
{
my $trace;
sub foo {
$trace = Devel::StackTrace->new
};
{ my $obj_to_be_destroyed = bless {} }
print $trace->as_string
}
print "the end\n"
'
The fix (as per https://github.com/dbsrgits/dbix-class/pull/63#issuecomment-60512767) is:
Devel::StacklTrace must be adjusted to detect it is constructing a stacktrace from within DESTROY (by examining (caller($n))[3] and not create any new refs to the refaddr of the argument to any DESTROY frames found.
This issue is also likely the real underlying reason for https://rt.cpan.org/Ticket/Display.html?id=99095