On Fri Dec 05 09:28:54 2014, SPROUT wrote:
Show quoted text> I think that by the time CvGV reifies the GV, you have already
> recorded the RV that you followed to get to it. Since it is the RV
> itself that gets upgraded to a typeglob, referential identity results
> in a CvGV pointing to the RV.
>
> So, either you can check, when you have a sub ref, whether
> CvGV(SvRV(ref)) modifies ref, before dumping it (may be problematic if
> you have already processed a reference to that RV); or you could check
> !CvNAMED(cv) before processing CvGV, to avoid vivifying anything
> during the dump.
So my code is now:
if(!CvNAMED(cv))
write_svptr(fh, (SV*)CvGV(cv));
else
write_svptr(fh, NULL);
And unfortunately I'm still getting CV "glob" slots that claim to point directly to REFs. This is the only occurrence of CvGV in the code.
More specifically, throughout the entire memory dump, the only two CVs I can find with these odd glob slots are normal named functions defined in the main script; every single function that appears in the symbol table from other files has a proper GV.
This is even true of nontrivially-small programs - if I load half of IO::Async, for example, then again every single CV in the IO::Async:: and below namespace appears to have a real GV in its CvGV slot; not a single function is found without one.
In case it is of interest, the program that can create these odd CVs is
https://metacpan.org/source/PEVANS/Devel-MAT-0.20/t/02contexts.t
What is notable about those functions is that both of them are "live" on the callstack at the time the heap is dumped; though the same can also be said for the (XS) heap dumping function itself; and that retains a perfectly normal GV in this file.
I remain confused.
--
Paul Evans