develooper Front page | perl.perl5.porters | Postings from March 2003

Re: [perl #21614] 5.8.0 Unbalanced string table refcount

Thread Previous | Thread Next
From:
Nicholas Clark
Date:
March 23, 2003 13:51
Subject:
Re: [perl #21614] 5.8.0 Unbalanced string table refcount
Message ID:
20030323214622.GJ281@Bagpuss.unfortu.net
On Sun, Mar 23, 2003 at 05:59:59PM +0000, Nicholas Clark wrote:
> OK. My suspicions were wrong, in that it's not a UTF8 local issue.
> Also I was wrong in my understanding of the string table - the string table
> warning occurs independent of -DDEBUGGING

> However, I can't be sure if this illegal memory access is actually the
> same bug as you're seeing. I'm a bit confused by all this, because valgrind
> seems to be reporting errors in the pad code, and pads have been substantially
> reworked for bleadperl, but not maintperl. Hence I'm surprised that the bug
> seems to be fixed in both branches, given that the implementation differs.

It's probably a different bug you're seeing. I suspect it's the same as this
bug:

$ ./perl -Ilib -lwe '%hash = ("perl"=>"rules"); foreach (sort keys %hash) {while (<>) {}}'
Segmentation fault (core dumped)

(for -DPERL_COPY_ON_WRITE)

I'm not quite sure what the correct fix is. The problem is that
do_readline calls Sv_Grow

	tmplen = SvLEN(sv);	/* remember if already alloced */
	if (!tmplen)
	    Sv_Grow(sv, 80);	/* try short-buffering it */


SvLEN() is 0 for a shared hash key scalar, so the if is true.

sv_grow ends up in this else block:

        else {
	    New(703, s, newlen, char);
	    if (SvPVX(sv) && SvCUR(sv)) {
	        Move(SvPVX(sv), s, (newlen < SvCUR(sv)) ? newlen : SvCUR(sv), char);
	    }
	}
	SvPV_set(sv, s);
        SvLEN_set(sv, newlen);

and at the end of that the shared hash key scalar:

SV = PVIV(0x812f820) at 0x812f15c
  REFCNT = 2
  FLAGS = (POK,FAKE,READONLY,pPOK)
  UV = 3023084856  (HASH)
  PV = 0x812e3a8 "perl"
  CUR = 4
  LEN = 0

becomes the (incorrect)

SV = PVIV(0x812f820) at 0x812f15c
  REFCNT = 2
  FLAGS = (POK,FAKE,READONLY,pPOK)
  UV = 3023084856  (COW from 0xb4309d38)
  PV = 0x8130180 "perl"
  CUR = 4
  LEN = 80

(FAKE and READONLY should be off)


I'm not sure how to solve this. The correct thing to do would be to call
force_normal from sv_grow (if needed). But force_normal will allocate a
minimally sized buffer using malloc(), only for sv_grow to want to extend it
again. And I'm loathe to duplicate the un-COW logic into sv_grow.

But it would explain how the warning about unbalanced string tables.
(Even for 5.8.0, which can't do copy on write)

Nicholas Clark

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