|Do you know where your variables are?|
Segfault with Devel::Sizeby wanna_code_perl (Pilgrim)
|on Aug 22, 2013 at 10:15 UTC||Need Help??|
wanna_code_perl has asked for the
wisdom of the Perl Monks concerning the following question:
I'm using Devel::Gladiator to get a list of all refs in use by Perl, which I want to (among other things) calculate the allocated size of with Devel::Size. This is the only way I could find to profile memory usage of unknown variables with reasonable accuracy without requiring a custom recompile of Perl to enable Perl malloc.It almost works. Unfortunately, Devel::Size is segfaulting trying to calculate the size() of a handful of SCALAR refs (and so far no other kind of ref). So far the affected deref'd scalars contain variable names used/exported by various core pragmas, specifically, one of (no particular order):
Here's a short script that demonstrates the issue. I've tried this on 5.14, 5.17.x, and 5.18.1, and crashes every time I run it.
I get output like:
The crash occurs on size($_) (or total_size($arena)), not when printing $$_. I'm not surprised to have issues working with every SV in existence. My best workaround so far has been to use length() to put a lower bound on the size of scalars, instead of size(). This obviously can be wrong by an arbitrarily large factor, as in $ooo = 'o' x 2**20; $ooo = '';, which leaves $ooo with a length of 0, and a size over 1 MB. I could also skip scalars whose contents match any of the above strings, but that's thousands of string comparisons, and without knowing why these specific refs cause a core dump, this seems like the kind of hack that is likely to blow up in my face if another ref with the same problem comes along later.
So, I ask, can anyone shed any light on what's going on, here? I'm more than happy to file a bug if I'm not doing something stupid, but I'd be even happier to learn a stable way to iterate all refs in existence and calculate their sizes, or at least safely skip the few that are going to be problematic. Hopefully this all makes sense.