Subject: | _install_method fails to set CvFILE correctly |
$ perl5.15.9 -MDBI -MDevel::Peek -le 'Dump +DBI::db->can("FETCH")'
SV = IV(0x834d0c) at 0x834d10
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0x89b590
SV = PVCV(0x8a9ec0) at 0x89b590
REFCNT = 3
FLAGS = (ISXSUB)
COMP_STASH = 0x0
XSUB = 0x1bc110
XSUBANY = 2995200
GVGV::GV = 0x89b580 "DBI::common" :: "FETCH"
FILE = "pan/build/namespace-clean-0.23-sEAgdO/blib/lib/Devel/Peek.pmc"
DEPTH = 0
FLAGS = 0x8
OUTSIDE_SEQ = 0
PADLIST = 0x0
OUTSIDE = 0x0 (null)
Notice that strange FILE string.
The documentation for newXS says:
I<filename> needs to be static storage, as it is used directly as CvFILE(), without a copy being
made.
But DBI is using the pv from inside the SV passed to _install_method. So CvFILE ends up
pointing to freed memory, which may get reused by the time CvFILE is looked at.
In perl 5.8.8 and earlier, the only way to fix this is to leak the file name, which is exactly what
perl itself did for constant subs. perl 5.8.1 has this on line 4436 of op.c:
cv = newXS(name, const_sv_xsub, savepv(CopFILE(PL_curcop)));
Starting with 5.10.0 and 5.8.9, there is an undocumented newXS_flags function, used pretty
much everywhere (so there’s little chance it will change), whose signature is:
CV *
Perl_newXS_flags(pTHX_ const char *name, XSUBADDR_t subaddr,
const char *const filename, const char *const proto,
U32 flags)
One of the flags it accepts is XS_DYNAMIC_FILENAME, which tells it to copy the filename
passed to it, and free it at the same time the CV itself is freed.
As currently written, _install_method might as well pass NULL for the filename, because its
not accomplishing anything by passing a scalar about to be freed.