Skip Menu |

This queue is for tickets about the Class-Unload CPAN distribution.

Report information
The Basics
Id: 129771
Status: new
Priority: 0/
Queue: Class-Unload

People
Owner: Nobody in particular
Requestors: myrrhlin [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: symbol table empty, but Foo:__ANON__ lives on
Date: Fri, 7 Jun 2019 23:20:16 -0400
To: bug-Class-Unload [...] rt.cpan.org
From: Michael Hamlin <myrrhlin [...] gmail.com>
howdy, first, thank you for your contributions to cpan, particularly in the DBIx:Class realm ! I was writing tests for a module's heavily customized import behavior, and tried using Class::Unload to remove it from memory and "use" it again with different parameters in subsequent tests. However, some symbols remained defined and usable even after clearing the symbol table -- function symbols created with typeglobs. They are somehow not in the symbol table for that package, and yet have the same names... I came up with this reduced example. $ perl -MClass::Unload -MFoo -MDDP -E' p %Foo::;say Foo::darn(); Class::Unload->unload("Foo"); p%Foo::;say Foo::darn()' { __ANON__ *Foo::__ANON__ (layers: ), AUTOLOAD *Foo::AUTOLOAD (layers: ), BEGIN *Foo::BEGIN (layers: ), carp *Foo::carp (layers: ), confess *Foo::confess (layers: ), croak *Foo::croak (layers: ), darn *Foo::darn (layers: ), import *Foo::import (layers: ), packagevar *Foo::packagevar (layers: ) } defined sub Foo::darn yep {} yeq $ cat Foo.pm package Foo; our $AUTOLOAD; our $packagevar = 'yep'; sub AUTOLOAD { my $sub = *{"$AUTOLOAD"} = sub {return $packagevar++}; print "defined sub $AUTOLOAD\n"; return $sub->(); } 1; This is a weird one, I'm not certain what's going on here -- kind of voodoo, to me. It makes sense to me that there's a closure around the variable, and so it lives on in anonymity, but how is it possible to still refer to the closure by the package name after the symbol table is cleared? I contrived a case to make the closure Carp::confess in the second call, and confess reports the stacktrace begins with Foo::__ANON__() which is doubly strange because 1) the Foo symbols table is empty, no __ANON__ left in it, and 2) the source code is calling it by name "Foo::darn". Is there any way to find this closure and unload it after all? (the finding part would be the trick...) Perhaps this one should better go on stack overflow. Thanks for looking, sir! michael PS. this is system perl on CentOS Linux release 7.5.1804 (Core $ perl -v This is perl 5, version 16, subversion 3 (v5.16.3) built for x86_64-linux-thread-multi (with 33 registered patches, see perl -V for more detail)
Subject: Re: [rt.cpan.org #129771] AutoReply: symbol table empty, but Foo:__ANON__ lives on
Date: Sun, 23 Jun 2019 22:07:47 -0400
To: bug-Class-Unload [...] rt.cpan.org
From: Michael Hamlin <myrrhlin [...] gmail.com>
i think we can close this report... i have a slightly better understanding of what's going on. Though it remains mysterious, I can accept that we can't do anything better.! deleting the symbol doesn't actually purge the code because there's still one or more references to it, and the code will remain in memory regardless of the symbol. thanks! michael PS I think (guessing here) you can call the sub by name because the call by name (both, actually) was replaced internally by some kind of dynamic reference during compile phase. At first invocation, the reference doesn't point to anything, so AUTOLOAD is called (and creates a symbol and code reference for it), and the referred code lives on past its symbol because there are two references to it in the package. not sure there's any way to reduce scope so that the reference count on this "thunk" goes to zero and it can be purged. On Fri, Jun 7, 2019 at 11:20 PM Bugs in Class-Unload via RT < bug-Class-Unload@rt.cpan.org> wrote: Show quoted text
> > Greetings, > > This message has been automatically generated in response to the > creation of a trouble ticket regarding: > "symbol table empty, but Foo:__ANON__ lives on", > a summary of which appears below. > > There is no need to reply to this message right now. Your ticket has been > assigned an ID of [rt.cpan.org #129771]. Your ticket is accessible > on the web at: > > https://rt.cpan.org/Ticket/Display.html?id=129771 > > Please include the string: > > [rt.cpan.org #129771] > > in the subject line of all future correspondence about this issue. To do > so, > you may reply to this message. > > Thank you, > bug-Class-Unload@rt.cpan.org > > ------------------------------------------------------------------------- > howdy, > > first, thank you for your contributions to cpan, particularly in the > DBIx:Class realm ! > > I was writing tests for a module's heavily customized import behavior, and > tried using Class::Unload to remove it from memory and "use" it again with > different parameters in subsequent tests. However, some symbols remained > defined and usable even after clearing the symbol table -- function symbols > created with typeglobs. They are somehow not in the symbol table for that > package, and yet have the same names... > > I came up with this reduced example. > > $ perl -MClass::Unload -MFoo -MDDP -E' > p %Foo::;say Foo::darn(); > Class::Unload->unload("Foo"); > p%Foo::;say Foo::darn()' > { > __ANON__ *Foo::__ANON__ (layers: ), > AUTOLOAD *Foo::AUTOLOAD (layers: ), > BEGIN *Foo::BEGIN (layers: ), > carp *Foo::carp (layers: ), > confess *Foo::confess (layers: ), > croak *Foo::croak (layers: ), > darn *Foo::darn (layers: ), > import *Foo::import (layers: ), > packagevar *Foo::packagevar (layers: ) > } > defined sub Foo::darn > yep > {} > yeq > $ cat Foo.pm > package Foo; > our $AUTOLOAD; > our $packagevar = 'yep'; > sub AUTOLOAD { > my $sub = *{"$AUTOLOAD"} = sub {return $packagevar++}; > print "defined sub $AUTOLOAD\n"; > return $sub->(); > } > 1; > > This is a weird one, I'm not certain what's going on here -- kind of > voodoo, to me. It makes sense to me that there's a closure around the > variable, and so it lives on in anonymity, but how is it possible to still > refer to the closure by the package name after the symbol table is cleared? > > I contrived a case to make the closure Carp::confess in the second call, > and confess reports the stacktrace begins with Foo::__ANON__() > which is doubly strange because 1) the Foo symbols table is empty, no > __ANON__ left in it, and 2) the source code is calling it by name > "Foo::darn". > > Is there any way to find this closure and unload it after all? (the > finding part would be the trick...) > > Perhaps this one should better go on stack overflow. Thanks for looking, > sir! > > michael > > PS. this is system perl on CentOS Linux release 7.5.1804 (Core > $ perl -v > This is perl 5, version 16, subversion 3 (v5.16.3) built for > x86_64-linux-thread-multi > (with 33 registered patches, see perl -V for more detail) >