Bug #20138 glibc reports double free in more_results()/finish()
Submitted: 30 May 2006 6:35 Modified: 2 Jan 2007 22:51
Reporter: Paul Lucassen Email Updates:
Status: Can't repeat Impact on me:
None 
Category:Connectors: DBD::mysql ( Perl ) Severity:S2 (Serious)
Version:3.0006_1, 3.0004_1 OS:Linux (SLES9 / Suse9.3)
Assigned to: CPU Architecture:Any

[30 May 2006 6:35] Paul Lucassen
Description:
When calling more_results() on a statement handler when using server side prepared statements, the script crashes with '*** glibc detected *** double free or corruption'.
When using emulated prepared statements, the same happens when calling finish().
The script below can be used to construct both cases.
These problems appeared when moving from 3.0003_1 to 3.0004_1.

How to repeat:
#!/usr/bin/perl -w

use DBI;

my $emulate = 0;
#my $emulate = 1;

my $dbh = DBI->connect("DBI:mysql:test:localhost;mysql_emulated_prepare=$emulate",'pgl','');
my $sth = $dbh->prepare( "SELECT 1=0" )                or die $DBI::err." : ".$DBI::errstr;
$sth->execute()                                        or die $DBI::err." : ".$DBI::errstr;
my $res = $sth->fetchall_arrayref();

if ($emulate) {
    # this fails with: *** glibc detected *** double free or corruption (!prev): 0x082cafe8 ***
    while ($sth->more_results()) { $sth->finish(); };
} else {
    # this fails with: *** glibc detected *** double free or corruption (!prev): 0x082cafe8 ***
    while ($sth->more_results()) {  };
}
[30 May 2006 6:35] Paul Lucassen
This is rather serious, as it crashes the scripts.
[2 Jun 2006 7:07] Paul Lucassen
The problem probably has to do with repeated use of mysql_free_result internally. In a C program that call mysql_free_result repeatedly on the same resultset, the same error occurs. A solution could be to wrap mysql_free_result and test the result-set for validity before calling it, as hinted in http://dev.mysql.com/doc/refman/5.0/en/mysql-free-result.html.
(It would probably be better overall if the Mysql C api provided a validity test for result sets, or that the implementation of mysql_free_result be more careful.)
[12 Jun 2006 5:17] Paul Lucassen
In DBD::mysql 3.0006_1 this bug still exists.
[4 Jul 2006 10:42] Valeriy Kravchuk
Verified just as described:

openxs@suse:~/dbs/5.0> perl -w 20138.pl

Emulation of prepared statements: 1, version: 3.0006_1
*** glibc detected *** double free or corruption (!prev): 0x082df260 ***
Aborted
openxs@suse:~/dbs/5.0> vi 20138.pl
openxs@suse:~/dbs/5.0> perl -w 20138.pl

Emulation of prepared statements: 0, version: 3.0006_1
*** glibc detected *** double free or corruption (!prev): 0x081c7918 ***
Aborted
openxs@suse:~/dbs/5.0> cat 20138.pl
#!/usr/bin/perl -w

use DBI;

#my $emulate = 0;
my $emulate = 0;

my $dbh =
DBI->connect("DBI:mysql:test:127.0.0.1;mysql_emulated_prepare=$emulate",'root','
'
);

print "\nEmulation of prepared statements: $emulate, version: $DBD::mysql::VERSI
ON\n";

my $sel = "SELECT 1=0";
my $sth = $dbh->prepare( $sel )                or die $DBI::err." :
".$DBI::errstr;
$sth->execute()                                        or die $DBI::err." :
".$DBI::errstr;
my $res = $sth->fetchall_arrayref();

if ($emulate) {
    while ($sth->more_results()) { $sth->finish(); };
} else {
    while ($sth->more_results()) {  };
}
[2 Jan 2007 22:51] Jim Winstead
I can't repeat this with the latest development source of DBD::mysql (which will be 4.001).