destruction ordering in DBI
[email protected] (Nicholas Clark) Wed, 3 Nov 2004 18:34:39 +0000
| Newsgroups | perl.ponie.dev |
|---|---|
| Message-ID | <[email protected]> |
Whilst this might seem an inappropriate place to mail this, I believe that
Tim Bunce is subscribed, so I'm going to fire away.
I can get segfaults in DBI from the regression tests for DBD-SQLite (0.31)
It comes down to a destruction ordering problem (I believe). valgrind
reports:
==14963== Invalid read of size 4
==14963== at 0x3DD1CB33: XS_DBI_dispatch (DBI.xs:2507)
==14963== by 0x8139261: Perl_pp_entersub (pp_hot.c:2798)
==14963== by 0x80BA4B0: S_call_body (perl.c:2167)
==14963== by 0x80BA143: Perl_call_sv (perl.c:2088)
==14963== by 0x8148BD1: Perl_sv_clear (sv.c:5733)
==14963== by 0x8149BE7: Perl_sv_free2 (sv.c:6010)
==14963== by 0x8149484: Perl_sv_clear (sv.c:5837)
==14963== by 0x8149BE7: Perl_sv_free2 (sv.c:6010)
==14963== by 0x8125CE6: Perl_hv_free_ent (hv.c:1434)
==14963== by 0x81264E0: S_hfreeentries (hv.c:1608)
==14963== by 0x812656A: Perl_hv_undef (hv.c:1634)
==14963== by 0x814920C: Perl_sv_clear (sv.c:5802)
==14963== by 0x8149BE7: Perl_sv_free2 (sv.c:6010)
==14963== by 0x813AB58: do_clean_objs (sv.c:331)
==14963== by 0x813A8B1: S_ptr_table_visit (sv.c:263)
==14963== by 0x813A908: S_visit (sv.c:282)
==14963== by 0x813AF70: Perl_sv_clean_objs (sv.c:370)
==14963== by 0x80B5AB4: perl_destruct (perl.c:446)
==14963== Address 0x3E55B7F0 is 60 bytes inside a block of size 85 free'd
==14963== at 0x3C01E72D: free (vg_replace_malloc.c:127)
==14963== by 0x8112284: Perl_safesysfree (util.c:145)
==14963== by 0x81494F1: Perl_sv_clear (sv.c:5859)
==14963== by 0x8149BE7: Perl_sv_free2 (sv.c:6010)
==14963== by 0x811A6F2: Perl_mg_free (mg.c:405)
==14963== by 0x8149012: Perl_sv_clear (sv.c:5774)
==14963== by 0x8149BE7: Perl_sv_free2 (sv.c:6010)
==14963== by 0x813AB58: do_clean_objs (sv.c:331)
==14963== by 0x813A8B1: S_ptr_table_visit (sv.c:263)
==14963== by 0x813A908: S_visit (sv.c:282)
==14963== by 0x813AF70: Perl_sv_clean_objs (sv.c:370)
==14963== by 0x80B5AB4: perl_destruct (perl.c:446)
==14963== by 0x80B3F0D: main (perlmain.c:88)
==14963==
==14963== ---- Attach to debugger ? --- [Return/N/n/Y/y/C/c] ---- y
Line 2507 is the last one of these:
/* record this inner handle for use by DBI::var::FETCH */
if (is_DESTROY) {
if (DBIc_TYPE(imp_xxh) <= DBIt_DB ) { /* is dbh or drh */
imp_xxh_t *parent_imp;
if (SvOK(DBIc_ERR(imp_xxh)) && (parent_imp = DBIc_PARENT_COM(imp_xxh)) ) {
/* copy err/errstr/state values to $DBI::err etc still work */
sv_setsv(DBIc_ERR(parent_imp), DBIc_ERR(imp_xxh));
sv_setsv(DBIc_ERRSTR(parent_imp), DBIc_ERRSTR(imp_xxh));
sv_setsv(DBIc_STATE(parent_imp), DBIc_STATE(imp_xxh));
Which is the lookup of the SV Err in this structure:
typedef struct dbih_com_attr_st {
/* These are copies of the Hash values (ref.cnt.inc'd) */
/* Many of the hash values are themselves references */
SV *TraceLevel;
SV *State; /* Standard SQLSTATE, 5 char string */
SV *Err; /* Native engine error code */
SV *Errstr; /* Native engine error message */
UV ErrCount;
U32 LongReadLen; /* auto read length for long/blob types */
SV *FetchHashKeyName; /* for fetchrow_hashref */
/* (NEW FIELDS?... DON'T FORGET TO UPDATE dbih_clearcom()!) */
} dbih_com_attr_t;
in the parent. (parent_imp)
The problem is that parent_imp has already been free()d, and it seems that
the child has no way of knowing this. It's probably a real DBI bug, but it's
hard to make it show up reliably on ponie, let alone conventional perl 5.
However, it might not be (quite) a real DBI bug, as currently ponie's SV
structure isn't totally like perl5's - SvRV() and SvPVX() aren't pointing to
the same piece of memory.
Nicholas Clark