Front page | perl.perl5.porters |
Postings from April 2013
[perl #117793] Extend SvREFCNT* to work on any perl variable type
Thread Next
From:
Dominic Hargreaves
Date:
April 28, 2013 21:39
Subject:
[perl #117793] Extend SvREFCNT* to work on any perl variable type
Message ID:
rt-3.6.HEAD-28177-1367185164-1512.117793-75-0@perl.org
# 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)
Thread Next
-
[perl #117793] Extend SvREFCNT* to work on any perl variable type
by Dominic Hargreaves