develooper Front page | perl.perl5.porters | Postings from June 2011

[perl #93454] 7d6175e breaks each.t and hash.t with -DDEBUGGING, PERL_DESTRUCT_LEVEL

Craig A . Berry
June 24, 2011 01:56
[perl #93454] 7d6175e breaks each.t and hash.t with -DDEBUGGING, PERL_DESTRUCT_LEVEL
Message ID:
# New Ticket Created by  Craig A. Berry 
# Please include the string:  [perl #93454]
# in the subject line of all future correspondence about this issue. 
# <URL: >

With PERL_DESTRUCT_LEVEL set in the environment on a -DDEBUGGING build, t/op/hash.t and t/op/each.t now end with:

Unbalanced string table refcount: (1) for "a" during global destruction.

On VMS, this causes the tests to fail like so:

t/op/each......................................................FAILED--unexpected output at test 56
t/op/hash......................................................FAILED--unexpected output at test 9

Presumably due to some difference in the test driver, the tests don't fail on other platforms even though the warning is easily reproducible.  I've bisected it on Mac OS X with results below.

This is the report from git bisect:

7d6175ef71f6339fae97e36c1cdae9e4f47f74d0 is the first bad commit
commit 7d6175ef71f6339fae97e36c1cdae9e4f47f74d0
Author: Father Chrysostomos <>
Date:   Sun Jun 12 14:46:44 2011 -0700

    Completely free hashes containing nulls
    This fixes a regression introduced since 5.14.0, by commit e0171a1a3.
    The new Perl_hfree_next_entry function that that commit introduced
    returns the value of the hash element, or NULL if there are none left.
    If the value of the hash element is NULL, the two cases are indistin-
    Before e0171a1a3, all the hash code took null values into account.
    mro_package_moved took advantage of that, stealing values out of a
    hash and leaving it to the freeing code to delete the elements.
    The two places that call Perl_hfree_next_entry (there was only one,
    S_hfreeentries, with commit e0171a1a3, but the following commit,
    104d7b699c, made sv_clear call it, too) were not accounting for NULL
    values’ being returned, and could terminate early, resulting in mem-
    ory leaks.
    One could argue that the perl core should not be assigning nulls to
    HeVAL, but HeVAL is part of the public API and there could be CPAN
    code assigning NULL to it, too.
    So the safest approach seems to be to modify Perl_hfree_next_entry’s
    callers to check the number of keys and not to attribute a signifi-
    cance to a returned NULL.

:040000 040000 49c4c8eae8aff3a90bce904cb698542878aa3563 52262ef3e181def0d84640b6768b3666678479ee M	ext
:100644 100644 51c782a3bfcd4ca4aed07b50daf7240dbd5d5169 a230c167fcf73ce1ae04321ea9bfa5a3e002140d M	hv.c
:100644 100644 faddfdc8aa33bf52a0f9060cf7650c06646d7863 6750ef197ec952cf3261eb31810ea536962dad00 M	sv.c
bisect run success

This was my bisect script:

% cat ~/run
git clean -dxf

sh Configure -des -Dusedevel -DDEBUGGING
test -f || exit 125
make test_prep
[ -x ./perl ] || exit 125
set ret=0
./perl -Ilib t/op/hash.t 2>&tmp.log
grep -c 'global destruction' tmp.log
test $? -gt 0 || set ret=2
git clean -dxf
exit $ret

% ./perl -Ilib -V
Summary of my perl5 (revision 5 version 15 subversion 0) configuration:
  Commit id: 30b0736d971c494432c032b4ca9fd2e8dcd31680
    osname=darwin, osvers=10.7.0, archname=darwin-2level
    uname='darwin triamond.local 10.7.0 darwin kernel version 10.7.0: sat jan 29 15:17:16 pst 2011; root:xnu-1504.9.37~1release_i386 i386 '
    config_args='-Dusedevel -DDEBUGGING -des'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=undef, usemultiplicity=undef
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
    cc='cc', ccflags ='-fno-common -DPERL_DARWIN -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -I/opt/local/include',
    optimize='-O3 -g',
    cppflags='-fno-common -DPERL_DARWIN -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -I/opt/local/include'
    ccversion='', gccversion='4.2.1 (Apple Inc. build 5666) (dot 3)', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='env MACOSX_DEPLOYMENT_TARGET=10.3 cc', ldflags =' -fstack-protector -L/usr/local/lib -L/opt/local/lib'
    libpth=/usr/local/lib /opt/local/lib /usr/lib
    libs=-ldbm -ldl -lm -lutil -lc
    perllibs=-ldl -lm -lutil -lc
    libc=/usr/lib/libc.dylib, so=dylib, useshrplib=false, libperl=libperl.a
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=bundle, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags=' -bundle -undefined dynamic_lookup -L/usr/local/lib -L/opt/local/lib -fstack-protector'

Characteristics of this binary (from libperl): 
                        USE_64_BIT_INT USE_LARGE_FILES USE_LOCALE
  Built under darwin
  Compiled at Jun 23 2011 21:30:43

Craig A. Berry

"... getting out of a sonnet is much more
 difficult than getting in."
                 Brad Leithauser Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About