I think I've isolated the cause of my Apache::DProf seg-faults. The
seg-fault occurs inside Devel::DProf's prof_mark() routine. When it
occurs the magic PL_DBsub variable, known to Perl as $DB::sub contains:
SV = PVGV(0x8208960) at 0x970927c
REFCNT = 1
FLAGS = (GMG,SMG,MULTI)
IV = 0
NV = 0
MAGIC = 0x97173b8
MG_VIRTUAL = &PL_vtbl_glob
MG_TYPE = '*'
MG_OBJ = 0x970927c
NAME = "sub"
NAMELEN = 3
GvSTASH = 0x81fa380 "DB"
GP = 0x9717380
SV = 0x97156cc
REFCNT = 1
IO = 0x0
FORM = 0x0
AV = 0x0
HV = 0x97092dc
CV = 0x82085d0
CVGEN = 0x0
GPFLAGS = 0x0
LINE = 17
FILE = "/usr/local/lib/perl5/site_perl/5.6.1/i686-linux/Apache/DB.pm"
FLAGS = 0x2
EGV = 0x970927c "sub"
Then prof_mark() calls GvSV() on it and gets:
SV = PVIV(0x9730d60) at 0x97156cc
REFCNT = 1
FLAGS = (IOK,pIOK)
IV = 0
PV = 0
Which is then passed to INT2PTR() yielding a NULL pointer in a CV *, which
is later used. Bang.
Now, by tracing my app I've determined that this is happening when my main
mod_perl PerlHandler returns after certain operations (not all, but I
don't know what's special about the ones that cause the problem). In a
moment of madness I inserted this code into my handler():
$DB::sub += 0;
And it works! I have no idea why I thought this would work, but with that
line in my handler() I no longer get any seg-faults from Apache::DProf.
Question: how did $DB::sub get into a bad state such that GvSV()
produced an SV containing IV == 0 and PV == 0? Does anyone have any
suggestions as to how I could find out? I've been getting most of my info
via strategicly placed warn()s inside DProf.xs and gdb.
Thanks!
-sam