Hi,
I spotted some weird behavior in dbi.mysql.MysqlPreparedStatement?. Here's the program:
module pqtest;
import
dbi.mysql.all,
dbi.mysql.MysqlPreparedStatement,
tango.io.Console;
int main(char[][] args)
{
scope (success) Cout( "exit success" ).newline.flush;
scope (failure) Cout( "exit failure" ).newline.flush;
auto db = new MysqlDatabase("host=127.0.0.1;dbname=xxx", "yyy", "zzz");
assert ( db !is null );
scope (exit) db.close();
auto psp = new MysqlPreparedStatementProvider(db);
assert ( psp !is null );
auto pq = psp.prepare("select 1, 2, 3");
assert ( pq !is null );
pq.reset();
return 0;
}
Here's the output:
Attempting to register MysqlDatabase in Registry
exit success
*** glibc detected *** ./pqtest: free(): invalid pointer: 0xf7ee6170 ***
======= Backtrace: =========
/lib32/libc.so.6[0xf7e0c7a5]
/lib32/libc.so.6(cfree+0x85)[0xf7e100cd]
./pqtest[0x806c773]
./pqtest[0x8066702]
./pqtest[0x8061d5b]
./pqtest[0x80628ca]
./pqtest[0x80d9522]
./pqtest[0x80e38a2]
./pqtest[0x80e349a]
./pqtest[0x80e2998]
./pqtest[0x80de0bd]
./pqtest[0x80d8f2f]
./pqtest[0x80d8d41]
./pqtest[0x80d8cea]
/lib32/libc.so.6(__libc_start_main+0xe0)[0xf7db8428]
./pqtest(exit+0xb5)[0x804c621]
======= Memory map: ========
08048000-081c8000 r-xp 00000000 08:01 6292665 /home/od/prj/pna/pqtest
081c8000-08213000 rwxp 0017f000 08:01 6292665 /home/od/prj/pna/pqtest
08213000-08256000 rwxp 08213000 00:00 0 [heap]
f7b00000-f7b21000 rwxp f7b00000 00:00 0
f7b21000-f7c00000 ---p f7b21000 00:00 0
f7c88000-f7c94000 r-xp 00000000 08:01 4653072 /emul/ia32-linux/usr/lib/libgcc_s.so.1
f7c94000-f7c95000 rwxp 0000b000 08:01 4653072 /emul/ia32-linux/usr/lib/libgcc_s.so.1
f7c95000-f7c9e000 r-xp 00000000 08:01 4653365 /emul/ia32-linux/lib/libnss_files-2.7.so
f7c9e000-f7ca0000 rwxp 00008000 08:01 4653365 /emul/ia32-linux/lib/libnss_files-2.7.so
f7ca0000-f7da2000 rwxp f7ca0000 00:00 0
f7da2000-f7ee3000 r-xp 00000000 08:01 4653356 /emul/ia32-linux/lib/libc-2.7.so
f7ee3000-f7ee4000 r-xp 00141000 08:01 4653356 /emul/ia32-linux/lib/libc-2.7.so
f7ee4000-f7ee6000 rwxp 00142000 08:01 4653356 /emul/ia32-linux/lib/libc-2.7.so
f7ee6000-f7ee9000 rwxp f7ee6000 00:00 0
f7ee9000-f7f0c000 r-xp 00000000 08:01 4653360 /emul/ia32-linux/lib/libm-2.7.so
f7f0c000-f7f0e000 rwxp 00022000 08:01 4653360 /emul/ia32-linux/lib/libm-2.7.so
f7f0e000-f7f21000 r-xp 00000000 08:01 4653370 /emul/ia32-linux/lib/libpthread-2.7.so
f7f21000-f7f23000 rwxp 00012000 08:01 4653370 /emul/ia32-linux/lib/libpthread-2.7.so
f7f23000-f7f25000 rwxp f7f23000 00:00 0
f7f25000-f7f39000 r-xp 00000000 08:01 4653079 /emul/ia32-linux/usr/lib/libz.so.1.2.3.3
f7f39000-f7f3a000 rwxp 00013000 08:01 4653079 /emul/ia32-linux/usr/lib/libz.so.1.2.3.3
f7f5a000-f7f5d000 rwxp f7f5a000 00:00 0
f7f5d000-f7f79000 r-xp 00000000 08:01 4653353 /emul/ia32-linux/lib/ld-2.7.so
f7f79000-f7f7b000 rwxp 0001b000 08:01 4653353 /emul/ia32-linux/lib/ld-2.7.so
ffc38000-ffc3c000 rwxp ffc38000 00:00 0 [stack]
ffffe000-fffff000 r-xp ffffe000 00:00 0 [vdso]
Aborted
I tracked it back to the dtor of MysqlPreparedStatement?. The previous version was just:
mysql_stmt_close(stmt);
I changed it to:
if ( stmt !is null ) {
mysql_stmt_close(stmt);
stmt = null;
}
which helped. But:
tango.io.Console.Cerr("MysqlPreparedStatement.dtor of "~tango.text.convert.Integer.toString(cast(int)&this,tango.text.convert.Integer.Style.Hex)).newline.flush;
if ( stmt !is null ) {
tango.io.Console.Cerr("stmt was not null - closing").newline.flush;
mysql_stmt_close(stmt);
stmt = null;
}
else {
tango.io.Console.Cerr("stmt was null - ignoring").newline.flush;
}
as dtor yielded:
Attempting to register MysqlDatabase in Registry
exit success
MysqlPreparedStatement.dtor of ffffffffffbae97c
stmt was not null - closing
MysqlPreparedStatement.dtor of ffffffffffbae97c
stmt was null - ignoring
and therefor revealed that the dtor of this single instance got called twice! Whats going wrong here? I could not find any reasong for this.
Info on my configuration:
I have built DBI from trunk with DSSS using: buildflags=-version=dbi_mysql -debug=Log -llmysqlclient -llz
I have built the example code from above with DSSS using: buildflags=-version=dbi_mysql -llmysqlclient -llz -gc
System: Linux debian 2.6.22-3-amd64 #1 SMP Sun Nov 4 18:18:09 UTC 2007 x86_64 GNU/Linux
Compiler: Digital Mars D Compiler v1.025
Tango: Not completely sure but at least 0.99.4 or some trunk from 13.01.2008
I'll also try this with latest versions of DMD, GDC and tango and report if things change.
Kind regards,
Oliver