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):$VERSION $XS_VERSION %DeadBits %Bits %Offsets %EXPORT_TAGS $Verbose $ExportLevel $Debug %Cache @EXPORT_OK @ISA
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.
use strict; use warnings; use Devel::Gladiator qw/walk_arena/; use Devel::Size qw/size/; my $arena = walk_arena(); my $i = 0; $| = 1; for (@$arena) { next unless ref eq 'SCALAR'; next if not defined $$_; printf '%4d : %16s : "%s" :', $i++, $_, $$_; print size($_); print "\n"; } @$arena = ();
I get output like:
0 : SCALAR(0xf8a4f8) : "$" :56 1 : SCALAR(0xf8a510) : "::" :128 . . 21 : SCALAR(0xf3bbb0) : "1.03" :56 22 : SCALAR(0xf3bc10) : "Devel::Size" :85 23 : SCALAR(0xf3bc28) : "$VERSION" :Segmentation fault (core dumped)
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.
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Segfault with Devel::Size
by Anonymous Monk on Aug 22, 2013 at 10:20 UTC | |
by wanna_code_perl (Friar) on Aug 22, 2013 at 11:01 UTC |