develooper Front page | perl.perl5.porters | Postings from May 2013

Re: [perl #117793] Extend SvREFCNT* to work on any perl variable type

Thread Previous | Thread Next
From:
Brian Fraser
Date:
May 13, 2013 20:18
Subject:
Re: [perl #117793] Extend SvREFCNT* to work on any perl variable type
Message ID:
CA+nL+nbwC3=_ueKt9gL06HTrKsUkkFgAnaTYka0FnE6T+FCn5w@mail.gmail.com
On Sun, Apr 28, 2013 at 6:39 PM, Dominic Hargreaves <
perlbug-followup@perl.org> wrote:

> # New Ticket Created by  Dominic Hargreaves
> # Please include the string:  [perl #117793]
> # in the subject line of all future correspondence about this issue.
> # <URL: https://rt.perl.org:443/rt3/Ticket/Display.html?id=117793 >
>
>
>
> This is a bug report for perl from dom@earth.li,
> generated with the help of perlbug 1.39 running under perl 5.14.2.
>
>
> -----------------------------------------------------------------
> >From <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=401132>:
>
> "I recently discovered that Devel::Peek's SvREFCNT, SvREFCNT_inc
> and SvREFCNT_dec functions are not as flexible as the XS functions that
> they wrap.  In XS where you wish to get the reference count of an hash
> your HV * pointer will cast to an SV * when passed as an argument to
> SvREFCNT().  In Perl using Devel::Peek:SvREFCNT(%m) does not return the
> reference count of %m, but rather treats %m as a list of arguments to
> the function causing a runtime error.  I believe the intent of the code was
> to return the reference count of the parameter passed and the difference
> between Perl Prototypes and C casting was overlooked.
>     A small patch (attached) will extend these three functions to
> work on any perl variable type.  This could break code in cases where
> users expect an array of one member passed to these functions to operate
> on that only member of the array, but for all other data types (and
> arrays of any other length) these functions currently croak.  Possibly a
> new family of functions is warranted to maintain reverse compatibility
> in the single element array case in the existing functions, but it is
> not my place to make that judgement."
>
> ....
>
> "   "\%m" is a reference constructor, so SvREFCNT() ends up
> reporting the reference count of that newly constructed SV.  The
> situation can be illustrated with this small script:
>
> #!/usr/bin/perl
> use strict;
> use warnings;
> use Devel::Peek;
> my %m = (a => 'b');
> my $mr = \%m;
> Devel::Peek::Dump($mr);
> print Devel::Peek::SvREFCNT(\%m), "\n";
>
>     From the Dump you can see that %m (the PVHV) has a refcount of
> 2, but "Devel::Peek::SvREFCNT(\%m)" reports 1.  The reason for this can
> be illustrated by breaking that call up a little bit.  One would
> normally expect that:
>
> Devel::Peek::SvREFCNT(\%m)
>
> should be equivalent to
>
> my $tmp = \%m;
> Devel::Peek::SvREFCNT($tmp)
>
> which unsurprisingly reports a refcount of 1 for $tmp.  Nothing changes
> when $tmp is an immediate, unlabeled value on the argument stack to
> SvREFCNT() and I think that's expected and correct behavior.
>
>     The proposed patch solves this difficulty by always passing the
> argument from Perl by reference and then unconditionally dereferencing
> to access the target value."
>
> Patch attached for review.
>
> [Please do not change anything below this line]
> -----------------------------------------------------------------
> ---
> Flags:
>     category=core
>     severity=low
> ---
> Site configuration information for perl 5.14.2:
>
> Configured by Debian Project at Fri Apr 12 09:56:36 UTC 2013.
>
> Summary of my perl5 (revision 5 version 14 subversion 2) configuration:
>
>   Platform:
>     osname=linux, osvers=2.6.32-5-686-bigmem,
> archname=i486-linux-gnu-thread-multi-64int
>     uname='linux murphy 2.6.32-5-686-bigmem #1 smp mon feb 25 01:53:47 utc
> 2013 i686 gnulinux '
>     config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN
> -D_FORTIFY_SOURCE=2 -g -O2 -fstack-protector --param=ssp-buffer-size=4
> -Wformat -Werror=format-security -Dldflags= -Wl,-z,relro
> -Dlddlflags=-shared -Wl,-z,relro -Dcccdlflags=-fPIC
> -Darchname=i486-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.14
> -Darchlib=/usr/lib/perl/5.14 -Dvendorprefix=/usr
> -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5
> -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.14.2
> -Dsitearch=/usr/local/lib/perl/5.14.2 -Dman1dir=/usr/share/man/man1
> -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1
> -Dsiteman3dir=/usr/local/man/man3 -Duse64bitint -Dman1ext=1 -Dman3ext=3perl
> -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm
> -Ui_libutil -DDEBUGGING=-g -Doptimize=-O2 -Duseshrplib
> -Dlibperl=libperl.so.5.14.2 -des'
>     hint=recommended, useposix=true, d_sigaction=define
>     useithreads=define, usemultiplicity=define
>     useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
>     use64bitint=define, use64bitall=undef, uselongdouble=undef
>     usemymalloc=n, bincompat5005=undef
>   Compiler:
>     cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN
> -fstack-protector -fno-strict-aliasing -pipe -I/usr/local/include
> -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
>     optimize='-O2 -g',
>     cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fstack-protector
> -fno-strict-aliasing -pipe -I/usr/local/include'
>     ccversion='', gccversion='4.7.2', gccosandvers=''
>     intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678
>     d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
>     ivtype='long long', ivsize=8, nvtype='double', nvsize=8,
> Off_t='off_t', lseeksize=8
>     alignbytes=4, prototype=define
>   Linker and Libraries:
>     ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'
>     libpth=/usr/local/lib /lib/i386-linux-gnu /lib/../lib
> /usr/lib/i386-linux-gnu /usr/lib/../lib /lib /usr/lib
>     libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
>     perllibs=-ldl -lm -lpthread -lc -lcrypt
>     libc=, so=so, useshrplib=true, libperl=libperl.so.5.14.2
>     gnulibc_version='2.13'
>   Dynamic Linking:
>     dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
>     cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib
> -fstack-protector'
>
> Locally applied patches:
>
>
> ---
> @INC for perl 5.14.2:
>     /etc/perl
>     /usr/local/lib/perl/5.14.2
>     /usr/local/share/perl/5.14.2
>     /usr/lib/perl5
>     /usr/share/perl5
>     /usr/lib/perl/5.14
>     /usr/share/perl/5.14
>     /usr/local/lib/site_perl
>     .
>
> ---
> Environment for perl 5.14.2:
>     HOME=/home/dom
>     LANG=en_GB.UTF-8
>     LANGUAGE (unset)
>     LD_LIBRARY_PATH (unset)
>     LOGDIR (unset)
>     PATH=~/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
>     PERL_BADLANG (unset)
>     SHELL=/bin/bash
>
> --
> Dominic Hargreaves | http://www.larted.org.uk/~dom/
> PGP key 5178E2A5 from the.earth.li (keyserver,web,email)


If you really really need to mess with the refcounts, you might as well use
SvREFCNT directly (although you might want to write wrappers for _inc and
_dec, for sanity's sake):

&Internals::SvREFCNT(\@etc, 10);
&Internals::SvREFCNT(\*ENV, 0); # boom

Enjoy your rope!

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About