Subject: | Seg Fault when accessing column name metadata $sth-{NAME} |
I am getting a Segmentation Fault when trying to access statement column name metadata after a sqlite query via DBD::SQLite. I am using DBD::SQLite 1.07 (which uses SQLite v3.0.8) and Perl 5.8.0 built for i686-linux and i386-linux-thread-multi on Red Hat Linux 7.1 and 9.0.
I am trying to use DBD::SQLite as part of an open source project that will provide job accounting data to some of the nations largest supercomputing sites. As I use the Perl DBI to access the column names ($sth->{NAME}) after a SQLite query, a seg fault occurs after some number of accesses to the column names. For example, if I query a table with 12 columns and ask for the column names, it may segfault after successfully giving me the first five. If I put a warn statement in a random place in the dbdimp.c code, the number of columns successfully returned may change to 10 or 0 or even work for a number of queries to die in a later query's metadata lookup.
More specifically, here is the backtrace from a recent segfault on a dual proc i386 system:
Trying to read metadata (column names) via Perl DBI (DBD::SQLite) results in a Segmentation Fault in sqlite4ValueText.
gdb backtrace shows corrupt pVal:
0x40447c35 in sqlite3ValueText (pVal=0x1d9, enc=1 '\001') at vdbemem.c:672
672 warn("flags: %d", pVal->flags);
(gdb) where
#0 0x40447c35 in sqlite3ValueText (pVal=0x1d9, enc=1 '\001') at vdbemem.c:672
#1 0x40442d20 in sqlite3_value_text (pVal=0x1d9) at vdbeapi.c:47
#2 0x404437ce in columnName (pStmt=0x8cf8388, N=7,
xFunc=0x40442d00 <sqlite3_value_text>, useType=0) at vdbeapi.c:375
#3 0x40443803 in sqlite3_column_name (pStmt=0x8cf8388, N=7) at vdbeapi.c:384
#4 0x404181d2 in sqlite_st_FETCH_attrib (sth=0x846d740, imp_sth=0x8cde4b8,
keysv=0x8ceadf4) at dbdimp.c:629
#5 0x40406afd in XS_DBD__SQLite__st_FETCH_attrib (cv=0x8cd714c)
at SQLite.xsi:690
#6 0x403905c0 in XS_DBI_dispatch ()
from /usr/local/gold/lib/perl5/i686-linux/auto/DBI/DBI.so
#7 0x080a3c13 in Perl_pp_entersub ()
#8 0x0809de32 in Perl_runops_standard ()
#9 0x0805fc90 in S_call_body ()
#10 0x0805f85f in Perl_call_sv ()
#11 0x080969be in S_magic_methpack ()
#12 0x08096ab8 in Perl_magic_getpack ()
#13 0x08094fe4 in Perl_mg_get ()
#14 0x080a87b0 in Perl_sv_setsv_flags ()
#15 0x080ac31b in Perl_sv_mortalcopy ()
#16 0x080a1acb in Perl_pp_helem ()
#17 0x0809de32 in Perl_runops_standard ()
#18 0x0805f3fb in S_run_body ()
#19 0x0805f18a in perl_run ()
#20 0x0805cbc3 in main ()
#21 0x40081306 in __libc_start_main (main=0x805cb40 <main>, argc=4,
ubp_av=0xbffffb14, init=0x805bce8 <_init>, fini=0x80f5a70 <_fini>,
rtld_fini=0x4000d2dc <_dl_fini>, stack_end=0xbffffb0c)
at ../sysdeps/generic/libc-start.c:129
Running valgrind on the same code (with same version of SQLite) (incidentally on a different system) reveals that XS_DBI_dispatch is referencing a block of data that has already been freed.
==3209== Invalid read of size 4
==3209== at 0x473DC5B2: sqlite3_column_count (vdbeapi.c:289)
==3209== by 0x473DC88C: columnName (vdbeapi.c:366)
==3209== by 0x473DC909: sqlite3_column_name (vdbeapi.c:383)
==3209== by 0x473B26C8: sqlite_st_FETCH_attrib (dbdimp.c:628)
==3209== by 0x473A129A: XS_DBD__SQLite__st_FETCH_attrib (SQLite.xsi:690)
==3209== by 0x440FAEB0: XS_DBI_dispatch (DBI.xs:2663)
==3209== by 0x402B04E4: Perl_pp_entersub (pp_hot.c:2781)
==3209== by 0x40293C99: Perl_runops_debug (dump.c:1414)
==3209== by 0x40248758: S_call_body (perl.c:2069)
==3209== by 0x40248616: Perl_call_sv (perl.c:1948)
==3209== by 0x40247DE5: Perl_call_method (perl.c:1881)
==3209== by 0x4029C5BB: S_magic_methcall (mg.c:1328)
==3209== by 0x4029C734: S_magic_methpack (mg.c:1340)
==3209== by 0x4029C929: Perl_magic_getpack (mg.c:1353)
==3209== by 0x4029A336: Perl_mg_get (mg.c:128)
==3209== Address 0x45C58864 is 568 bytes inside a block of size 592 free'd
==3209== at 0x400296BF: free (vg_replace_malloc.c:220)
==3209== by 0x473D4030: sqlite3FreeX (util.c:283)
==3209== by 0x473DF158: sqlite3VdbeDelete (vdbeaux.c:1411)
==3209== by 0x473DEF2E: sqlite3VdbeFinalize (vdbeaux.c:1349)
==3209== by 0x473BF696: sqlite3_finalize (main.c:1223)
==3209== by 0x473B202E: sqlite_st_finish (dbdimp.c:523)
==3209== by 0x473B1B18: sqlite_st_fetch (dbdimp.c:457)
==3209== by 0x4739B78F: dbdxst_fetchall_arrayref (Driver_xst.h:97)
==3209== by 0x473A0255: XS_DBD__SQLite__st_fetchall_arrayref (SQLite.xsi:618)==3209== by 0x440FAEB0: XS_DBI_dispatch (DBI.xs:2663)
==3209== by 0x402B04E4: Perl_pp_entersub (pp_hot.c:2781)
==3209== by 0x40293C99: Perl_runops_debug (dump.c:1414)
==3209== by 0x402479AA: S_run_body (perl.c:1705)
==3209== by 0x40247634: perl_run (perl.c:1624)
==3209== by 0x80493A2: main (in /usr/bin/perl)
==3209==
Valgrind revealed numerous references to memory that had already been freed.
Thank you for any help you can give me on this!
Scott Jackson