Skip Menu |

This queue is for tickets about the DBD-Pg CPAN distribution.

Report information
The Basics
Id: 60863
Status: resolved
Priority: 0/
Queue: DBD-Pg

People
Owner: greg [...] turnstep.com
Requestors: szbalint [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 2.17.1
Fixed in: 2.18.0



Subject: An error with ShowErrorStatement active leaks memory
When the "ShowErrorStatement" DBI setting is active and an error happens, the error string seems to be leaking. Other DBI drivers do not seem to leak, so I'm opening this bug against DBD::Pg. I've attached a short script to reproduce the problem. (Thanks to ribasushi++ from #dbix-class for producing the testcase.)
Subject: leak.t
use strict; use warnings; use DBI; my ($dbi_dsn, $user, $pass) = map { $ENV{"DBICTEST_PG_$_"} } qw/DSN USER PASS/; my $dbh = DBI->connect($dbi_dsn, $user, $pass, { RaiseError => 1, PrintError => 0, ShowErrorStatement => 1 # <---- this is what makes the party go around }); $dbh->do ('DROP TABLE IF EXISTS errorstat_leak_hunt'); $dbh->do ('CREATE TABLE errorstat_leak_hunt (num INTEGER NOT NULL)'); my $sth = $dbh->prepare_cached('INSERT INTO errorstat_leak_hunt (num) VALUES (?)'); my $count; while (1) { $count++; eval { $sth->execute('non-num' x 200) }; unless ($count % 2000) { warn sprintf ("Cycles: %d\tProc size: %uK\n", $count, (-f "/proc/$$/stat") ? do { local @ARGV="/proc/$$/stat"; (split (/\s/, <>))[22] / 1024 } : -1 , ); } }
On Sun Aug 29 14:46:06 2010, SZBALINT wrote: Show quoted text
> When the "ShowErrorStatement" DBI setting is active and an error > happens, the error string seems to be leaking. > > Other DBI drivers do not seem to leak, so I'm opening this bug against > DBD::Pg. > > I've attached a short script to reproduce the problem. > > (Thanks to ribasushi++ from #dbix-class for producing the testcase.)
If I #ifdef out the following lines in DBI.xs the problem is solved so I guess it is something to do with sorting parameters for ShowErrorStatement: around line 3701: #ifdef FREDERICK if (!(ima_flags & IMA_HIDE_ERR_PARAMVALUES)) { svp = hv_fetch((HV*)DBIc_MY_H(imp_xxh),"ParamValues",11,FALSE); if (svp && SvMAGICAL(*svp)) mg_get(*svp); /* XXX may recurse, may croak. could use eval */ } #endif I'm actually suspicious of the following lines which sort the parameters but I have not isolated it further. Hope this helps. I don't have time right now to look at this but I might come back to it given some tuits. Martin -- Martin J. Evans Wetherby, UK
Thanks, this is a great hint: it's definitely a problem with the ParamValues hash. When I set it as empty, the memory leak still occurs but at a much smaller rate.
Using perl 5.12.2 I couldn't reproduce it with: perl -MDBI -we '$a = DBI::_concat_hash_sorted({1..10000},"=",",",1,1) while 1' nor with: perl -Mblib -MDBI -we '$sth=DBI->connect("dbi:NullP:",0,0,{ShowErrorStatement=>1})- Show quoted text
>prepare("ERROR 1 err"); $sth->execute(1..10000) while 1' 2> /dev/null
The ticket says "Other DBI drivers do not seem to leak" so I suspect the leak is in DBD::Pg's dbd_st_FETCH_attrib function (in dbdimp.c) where it handles the ParamValues attribute by constructing a hash. (That's called from DBI.xs by the mg_get(*svp);) Tim.
On Tue Feb 22 12:41:18 2011, TIMB wrote: Show quoted text
> Using perl 5.12.2 I couldn't reproduce it with: > > perl -MDBI -we '$a = > DBI::_concat_hash_sorted({1..10000},"=",",",1,1) while 1' > > nor with: > > perl -Mblib -MDBI -we '$sth=DBI-
> >connect("dbi:NullP:",0,0,{ShowErrorStatement=>1})- > >prepare("ERROR 1 err"); $sth->execute(1..10000) while 1' 2> /dev/null
> > The ticket says "Other DBI drivers do not seem to leak" so I suspect > the leak is in DBD::Pg's > dbd_st_FETCH_attrib function (in dbdimp.c) where it handles the > ParamValues attribute by > constructing a hash. (That's called from DBI.xs by the mg_get(*svp);) > > Tim.
This may be useful: http://www.perlmonks.org/?node_id=52609 as I noted, I use hv_store in DBD::ODBC and DBD::Pg uses hv_store_ent. It appears if you use hv_store_ent you may need to look more closely at the key - see the link above. Martin -- Martin J. Evans Wetherby, UK
On Tue Feb 22 13:38:24 2011, MJEVANS wrote: Show quoted text
> On Tue Feb 22 12:41:18 2011, TIMB wrote:
> > Using perl 5.12.2 I couldn't reproduce it with: > > > > perl -MDBI -we '$a = > > DBI::_concat_hash_sorted({1..10000},"=",",",1,1) while 1' > > > > nor with: > > > > perl -Mblib -MDBI -we '$sth=DBI-
> > >connect("dbi:NullP:",0,0,{ShowErrorStatement=>1})- > > >prepare("ERROR 1 err"); $sth->execute(1..10000) while 1' 2> /dev/null
> > > > The ticket says "Other DBI drivers do not seem to leak" so I suspect > > the leak is in DBD::Pg's > > dbd_st_FETCH_attrib function (in dbdimp.c) where it handles the > > ParamValues attribute by > > constructing a hash. (That's called from DBI.xs by the mg_get(*svp);) > > > > Tim.
> > This may be useful: > > http://www.perlmonks.org/?node_id=52609 > > as I noted, I use hv_store in DBD::ODBC and DBD::Pg uses hv_store_ent. > > It appears if you use hv_store_ent you may need to look more closely at > the key - see the link above. > > Martin
I think attached patch fixes this issue. Martin -- Martin J. Evans Wetherby, UK
Subject: patch
Download patch
application/octet-stream 1.3k

Message body not shown because it is not plain text.

Applied in r14720. Many thanks.
On Thu Feb 24 20:18:55 2011, greg@turnstep.com wrote: Show quoted text
> Applied in r14720. Many thanks.
It is possible a similar issue exists in ParamTypes and pg_bound where the hv_store_ent is called and the key is an SV but the reference count is not decremented. Not that I've checked - just noticed it. Martin -- Martin J. Evans Wetherby, UK
Show quoted text
> It is possible a similar issue exists in ParamTypes and pg_bound where > the hv_store_ent is called and the key is an SV but the reference count > is not decremented.
Thanks, these were adjusted as well.