PerlIO::via reference counting bug?
[email protected] (Nicholas Clark) Mon, 17 Oct 2005 14:35:46 +0100
| Newsgroups | perl.perl5.porters,perl.ponie.dev |
|---|---|
| Message-ID | <[email protected]> |
I've built ponie and hit "interesting" premature destruction of SVs.
Things go very pear shaped when the symbol tables are cleared up during
global destruction in lib/PerlIO/t/QuotedPrintable.t
The problem is that this PVGV is getting freed after test 9 of 11, but it's
still referenced by the symbol table:
(gdb) call Perl_sv_dump(sv)
SV = PVGV(0x8712218) at 0xf785f7cf [Perl5PVGV]
REFCNT = 0
FLAGS = (GMG,SMG)
IV = 0
NV = 0
MAGIC = 0x8713670
MG_VIRTUAL = &PL_vtbl_glob
MG_TYPE = PERL_MAGIC_glob(*)
MG_OBJ = 0xf785f7cf
NAME = "_GEN_1"
NAMELEN = 6
GvSTASH = 0xf78d00d7 "PerlIO::via::QuotedPrint"
GP = 0x87122f8
SV = 0xf785f7e7
REFCNT = 1
IO = 0xf785f7ff
FORM = 0x0
AV = 0x0
HV = 0x0
CV = 0x0
CVGEN = 0x0
GPFLAGS = 0x0
LINE = 64
FILE = "lib/PerlIO/via/t/QuotedPrint.t"
FLAGS = 0x0
EGV = 0xf785f7cf "_GEN_1"
The free is happening here in via.xs in PerlIOVia_popped:
if (s->fh) {
SvREFCNT_dec(s->fh);
s->fh = Nullsv;
s->io = NULL;
}
The only assignment I can find to s->fh is here in PerlIOVia_method:
if (!s->fh) {
GV *gv = newGVgen(HvNAME(s->stash));
GvIOp(gv) = newIO();
s->fh = newRV_noinc((SV *) gv);
s->io = GvIOp(gv);
}
What is that noinc? That appears to be the problem. A pointer is stored with
no increase in the reference count, and then when it is cleared up a
decrease is made. Surely that newRV_noinc should be a newRV_inc ?
Nicholas Clark