RE: memory leak in DBI XS bootstrap code
- From: E.Dan@xxxxxx (Ephraim Dan)
- Date: Wed, 12 Jul 2006 22:44:38 -0700
Did you try the other suggestions?
How much improvement did each give? (when testing by destroying the
interpreter)
Yeah, sorry I didn't give more detail on that. Here goes:
The first change (Doru Petrescu):
No change, still leaks 4 per connect/prepare/execute/fetch/disconnect loop.
The (av_len(av) % 120 == 0) change:
That does reduce it to 3 per loop, but I am not sure what you mean that it is not a leak - when it leaks 4, it's 4 every time - it's not stabilizing after some time, or jumping back down once in a while, or only leaking 3 sometimes, just going up and up by 4 every time. So how is that not a leak?
As I said, the "if (0)" on the whole chunk of code produces squeaky clean iterations.
-edan
So... do I need to keep this patched myself, at the risk of breaking
when the code changes in some future release, or can you somehow make
this optional, or fix it,
I'd probably accept a patch that adds an option to Makefile.PL that then
passes a -DDBI_NO_WEAKREFS to the compiler which, with a suitable
#ifndef in DBI.xs, would disable that code. Or a new per-handle
flag could be added.
But I'm reluctant to do either till I know more about the cause.
or explain to me what I can do to make the
leak go away using the current code?
I need more info - see above.
Tim.
Thanks so much,that's
edan
-----Original Message-----
From: Tim Bunce [mailto:Tim.Bunce@xxxxxxxxx]
Sent: Tuesday, July 11, 2006 16:59
To: Ephraim Dan
Cc: Tim Bunce; dbi-users@xxxxxxxx
Subject: Re: memory leak in DBI XS bootstrap code
I'm sorry but I simply don't have the time at the moment.
Some random suggestions:
- try using different sets of methods to isolate the minimum
requirements.
for example:
call fetchrow_array just once.
don't call fetchrow_array at all.
call fetchrow_array in loop but don't call finish
don't execute, fetch, finish.
etc etc etc
- try with other drivers to see if it's the driver or the DBI
perlgrief.leaking
Tim.
On Tue, Jul 11, 2006 at 03:59:05AM -0700, Ephraim Dan wrote:
Tim,
I'm experiencing further memory leaks which are causing me more
leakage:I put together the following test script which illustrates the
{RaiseError=>1});
#/usr/bin/perl
# dbi.pl
use DBI;
use Devel::Leak;
my $leak_handle;
for ( 1 .. 1000 ) {
my $dbh = DBI->connect("DBI:mysql:MYDB","user","secret",
my $sth = $dbh->prepare("SELECT COUNT(*) FROM TABLE");
$sth->execute();
while ( my ($c) = $sth->fetchrow_array() ) {
# print "$c\n";
}
$sth->finish;
$dbh->disconnect;
system("ps -aux | fgrep dbi.pl | fgrep -v fgrep");
test_leak();
}
sub test_leak {
if ( $handle ) {
Devel::Leak::CheckSV($handle);
}
print STDERR "count: " . Devel::Leak::NoteSV($handle) . "\n";
}
Devel::Leak shows that it is leaking 4 "things" every iteration:
count: 12128
root 17720 17.8 0.3 6840 4220 pts/0 S 09:55 0:00
connect()dbi.pl
new 0x8aad3e8 : SV = PVHV(0x8a68b30) at 0x8aad3e8
REFCNT = 1
FLAGS = (PADBUSY,PADMY,SHAREKEYS)
IV = 0
NV = 0
ARRAY = 0x0
KEYS = 0
FILL = 0
MAX = 7
RITER = -1
EITER = 0x0
new 0x8aad3f4 : SV = NULL(0x0) at 0x8aad3f4
REFCNT = 1
FLAGS = (PADBUSY,PADMY)
new 0x8aad400 : SV = NULL(0x0) at 0x8aad400
REFCNT = 1
FLAGS = (PADBUSY,PADMY)
new 0x8aad40c : SV = NULL(0x0) at 0x8aad40c
REFCNT = 1
FLAGS = (PADBUSY,PADMY)
count: 12132
I think there might be several leaks here. If I move the
guys.out
of the loop, it's leaking, but less - just one of those NULL SV
scared
Can you please help me track this down? I'm still a little
service.of
the DBI.xs internals, despite my recent exposure...
Thanks a lot,
edan
-----Original Message-----
From: Tim Bunce [mailto:Tim.Bunce@xxxxxxxxx]
Sent: Monday, July 03, 2006 12:16
To: Ephraim Dan
Cc: Tim Bunce; dbi-users@xxxxxxxx
Subject: Re: memory leak in DBI XS bootstrap code
On Sat, Jul 01, 2006 at 10:42:58PM -0700, Ephraim Dan wrote:
Thanks for the help Tim! You've really done me a great
of
I have created the following patch, which appears to fix all
DBI isthe
approval?leaks. Can you please review it, and give it your stamp of
I
am willing to use this patch if you approve it, until a new
that'savailable with the fixes.
Looks okay at first sight, except that Newz returns memory
performancebeen
previously.reset to zero bytes. You need to add the memzero I suggested
Might as well go into malloc_using_sv since it's not
already docritical.
Um, looks like CLONE plus _clone_dbis plus dbi_bootinit
sothe
right thing (your patch also fixes a leak on thread creation)
it'sthat's
okay. INIT_PERINTERP is harder to be sure about, but I think
PERINTERP)okay.
I'll apply the patch and add the memzero. Thanks edan.
Tim.
Thanks again,
edan
The patch:
--- DBI.xs.orig 2006-06-30 10:20:10.000000000 -0400
+++ DBI.xs 2006-07-02 04:59:32.000000000 -0400
@@ -171,7 +171,7 @@
dPERINTERP_SV; dPERINTERP_PTR(PERINTERP_t *,
\# define INIT_PERINTERP \
dPERINTERP;
\- Newz(0,PERINTERP,1,PERINTERP_t);
\+ PERINTERP = malloc_using_sv(sizeof(PERINTERP_t));
dbistate_st*)malloc_using_sv(sizeof(structsizeof(dbih_fdc_t),sv_setiv(perinterp_sv, PTR2IV(PERINTERP))
# undef DBIS
@@ -209,13 +209,29 @@
stc_s, sizeof(dbih_stc_t), fdc_s,
msg);
}
+static void *
+malloc_using_sv(STRLEN len)
+{
+ dTHX;
+ SV *sv = newSV(len);
+ return SvPVX(sv);
+}
+
+static char *
+savepv_using_sv(char *str)
+{
+ char *buf = malloc_using_sv(strlen(str));
+ strcpy(buf, str);
+ return buf;
+}
+
static void
dbi_bootinit(dbistate_t * parent_dbis)
{
dTHX;
INIT_PERINTERP;
- Newz(dummy, DBIS, 1, dbistate_t);
+ DBIS = (struct
versiondbistate_st));
/* store version and size so we can spot DBI/DBD
:mismatch
*/
DBIS->check_version = check_version;
@@ -3793,7 +3809,7 @@
ima->minargs = (U8)SvIV(*av_fetch(av, 0, 1));
ima->maxargs = (U8)SvIV(*av_fetch(av, 1, 1));
svp = av_fetch(av, 2, 0);
- ima->usage_msg = savepv( (svp) ? SvPV(*svp,lna)
savepv_using_sv(SvPV(*svp,"");
+ ima->usage_msg = (svp) ?
maxlna)) :
"";
ima->flags |= IMA_HAS_USAGE;
if (trace_msg && DBIS_TRACE_LEVEL >= 11)
sv_catpvf(trace_msg, ",\n usage: min %d,
wrote:%d,
'%s'",
-----Original Message-----
From: Tim Bunce [mailto:Tim.Bunce@xxxxxxxxx]
Sent: Friday, June 30, 2006 16:33
To: Ephraim Dan
Cc: Tim Bunce; dbi-users@xxxxxxxx
Subject: Re: memory leak in DBI XS bootstrap code
On Fri, Jun 30, 2006 at 04:08:46AM -0700, Ephraim Dan
willing toThis is why I love the perl community - you're
lastbenefithelp
even
though you don't have time, since
you care about your code, and that other people can
from
it.
But ... you sort of left a dangling "But" in your
stillpost.
Do
you
have a suggestion to fix the
_install_method problem?
I just ran valgrind with your fix - there seems to
mechanism tobe a
leaks?leak.
It is reported on DBI.xs line 216:
INIT_PERINTERP;
That looks to also have a Newz in it - is that what
Yes. It's basically a plain malloc and there's no
an SVfree it
later.
Can you suggest how to fix that one?
The trick is to use newSV to alloc memory in the form of
getsso that when the interpreter is destroyed the SV memory
myfreed
automatically.
The _install_method leak is reported on line 3800 (in
"");modified
DBI.xs) which validates your theory:
ima->usage_msg = savepv( (svp) ? SvPV(*svp,lna) :
----If you can fix these, I'll be forever in your debt...
As above, and as outlined previously, use an SV.
Something like this (completely untested):
static void *
malloc_using_sv(STRLEN len) {
SV *sv = newSV(len);
return SvPVX(sv);
}
static char *
savepv_using_sv(char *str) {
char *buf = malloc_using_sv(strlen(str));
strcpy(buf, str);
return buf;
}
Tim.
--edan
-----------------------------------------------------
that----
wrote:----
----
-----------------------------------
From: Tim Bunce [mailto:Tim.Bunce@xxxxxxxxx]
Sent: Fri 6/30/2006 11:35
To: Ephraim Dan
Cc: Tim Bunce; dbi-users@xxxxxxxx
Subject: Re: memory leak in DBI XS bootstrap code
On Fri, Jun 30, 2006 at 12:24:33AM -0700, Ephraim Dan
comes> > > I don't see what you mean in the "INSTALL" that
with
directory.perl
5.8.0 (that's what we're using).
> > The file called INSTALL in the perl source code
>
> That I knew. What are the special instructions
debugging?I'm
supposed
to
> find there? Am I supposed to build it with
meantCan
you
> specify what special configuration exactly you
canthat I
should
use?
I'm sorry. I should have checked myself first. You
Sneakybuild
perl
with
-DPURIFY to enable more precise leak detection.
> It looks like the leak in boot_DBI is on purpose:
> /* Remember the last handle used. BEWARE!
tostuff
here!
*/
> /* We want a handle reference but we don't want
wantincrement
*/
> /* the handle's reference count and we don't
Takeperl
to
try
*/
> /* to destroy it during global destruction.
tocare!
correct*/
> DBI_UNSET_LAST_HANDLE; /* ensure setup the
way
*/
>
> Why is this being done, and does anyone have a way
as afix
it?
Why
don't we want perl to destroy it?
Me, that's exactly what I want.
I don't believe that's a leak. It's just using an SV
wasreference
without telling perl its a reference. If perl knew it
ona
wouldreference
we'd get double-free warnings as the referenced value
be
freed
twice.
The leak is probably the DBIS structure itself:
Newz(dummy, DBIS, 1, dbistate_t);
That should probably be using along the lines of:
sv = newSV(sizeof(struct dbistate_st));
DBIS = (struct dbistate_st*)SvPVX(sv);
memzero(DBIS, sizeof(struct dbistate_st));
So the memory is allocated within an SV so gets freed
_install_method...global
destruction.
> Still looking into the other leak in
due toany
pointers still appreciated... Thanks for
your help so far, Tim.
I've taken a look at the code. I'd guess that it's
:savepnv:
ima->usage_msg = savepv( (svp) ? SvPV(*svp,lna)
code"");
But
Tim.
> -edan
>
> > > -----Original Message-----
> > > From: Tim Bunce [[1]mailto:Tim.Bunce@xxxxxxxxx]
> > > Sent: Thursday, June 29, 2006 14:47
> > > To: Ephraim Dan
> > > Cc: dbi-users@xxxxxxxx
> > > Subject: Re: memory leak in DBI XS bootstrap
helpleak> > >
> > > Try building perl with options to make valgrind
tracing
more
> > > effective (see perl's INSTALL file). That may
Ephraimyou
pinpoint
> > > the problem.
> > >
> > > Tim.
> > >
> > > On Thu, Jun 29, 2006 at 04:33:40AM -0700,
memoryDan
wrote:
> > > > I am experiencing what I believe to be a
because Ileak
in
the
DBI
> > > bootstrap code. This is a problem for me
overam
embedding perl in a
> > > long-running program, and DBI is being loaded
initand
routines:over, so
my program
> > > grows and grows.
> > > >
> > > > The problem appears to be in the following
/usr/lib/perl5/vendor_perl/5.8.0/i386-> > > >
> > > > boot_DBI (in
Perllinux-
thread-
> > > multi/auto/DBI/DBI.so)/usr/lib/perl5/vendor_perl/5.8.0/i386-linux-
> > > > XS_DBI__install_method (in
> > > thread-multi/auto/DBI/DBI.so)<[3]http://valgrind.org/> ) can be used to reproduce
> > > >
> > > > I am using DBI 1.51
> > > >
> > > > The tool "valgrind" ([2]http://valgrind.org
the
> > > leak using the following code:
> > > >
> > > > ---
> > > > File: embed_test.c
> > > > ---
> > > >
> > > > #include <EXTERN.h> /* from the
Perldistribution */
> > > > #include <perl.h> /* from the
Perldistribution */
> > > >
> > > > static PerlInterpreter *my_perl; /*** The
interpreter ***/
> > > > EXTERN_C void xs_init (pTHX); /***
embedding,dyn.
loading
***/
> > > >
> > > > int main(int argc, char **argv, char **env)
> > > > {
> > > > char *embedding[] = { "", "-e", "0" };
> > > > my_perl = perl_alloc();
> > > > perl_construct(my_perl);
> > > > perl_parse(my_perl, xs_init, 3,
o(char
ccopts)**)NULL);
> > > > PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
> > > > perl_run(my_perl);
> > > > eval_pv("use DBI", TRUE);
> > > > perl_destruct(my_perl);
> > > > perl_free(my_perl);
> > > > }
> > > >
> > > > ---
> > > > File: Makefile
> > > > ---
> > > >
> > > > CC_OPTS = $(shell perl -MExtUtils::Embed -e
ldopts)> > > > LD_OPTS = $(shell perl -MExtUtils::Embed -e
$(LD_OPTS)> > > >
> > > > EXE = embed_test
> > > >
> > > > $(EXE): xsinit.o embed_test.o
> > > > gcc -o $(EXE) embed_test.o xsinit.o
> > > >
> > > > embed_test.o: embed_test.c
> > > > gcc -c embed_test.c $(CC_OPTS)
> > > >
> > > > xsinit.o: xsinit.c
> > > > gcc -c xsinit.c $(CC_OPTS)
> > > >
> > > > xsinit.c:
> > > > perl -MExtUtils::Embed -e xsinit -- -
morexsinit.c
> > > >
> > > > clean:
> > > > rm -f *.o xsinit.c $(EXE)
> > > >
> > > > ---
> > > > EOF
> > > > ---
> > > >
> > > > Can anyone suggest a fix for this? I'd be
than
willing
to take a
> > > patch to DBI 1.51 as soon as someone has one.
> > > >
> > > > Thanks,
> > > > Ephraim Dan
> > > >
>
References
Visible links
1. mailto:Tim.Bunce@xxxxxxxxx
2. http://valgrind.org/
3. http://valgrind.org/
- Follow-Ups:
- Re: memory leak in DBI XS bootstrap code
- From: Tim Bunce
- Re: memory leak in DBI XS bootstrap code
- Prev by Date: Re: memory leak in DBI XS bootstrap code
- Next by Date: Teradata V2R6 connection failing
- Previous by thread: Re: memory leak in DBI XS bootstrap code
- Next by thread: Re: memory leak in DBI XS bootstrap code
- Index(es):
Relevant Pages
|
|