CC: | Stephen Marshall <smarshall [...] wsi.com> |
Subject: | Memory leak in DBD-Pg (lack of mortalization) |
Date: | Thu, 07 Sep 2006 14:28:17 -0400 |
To: | bug-DBD-Pg [...] rt.cpan.org |
From: | Stephen Marshall <smarshall [...] wsi.com> |
I've found a memory leak in DBD-Pg when the pg_notifies function is
called. The return value needs to be mortalized; the failure to do so
causes about 100 bytes of memory to be lost each time pg_notifies is called.
I have posted the one-line patch for this to the dbdpg project on
gborg. The same patch is also attached below.
I have a pair of perl scripts that demonstrates this problem and show
that the fix works. One scripts listens while the other does very
rapidfire notifications. I am happy to make these scripts available on
request.
On a related note, while looking through the code trying to understand
when variables should be "mortalized", it appeared to me that there are
three other memory leaks in dbdimp.c, in the function
dbd_st_FETCH_attrib. These are very minor, but I'm wondering if some
"mortalization" expert could check these to see if these return values
(retsv below) should be wrapped in a sv_2mortal call?
Thanks,
Steve Marshall
----
Code with possible memory leaks at return retsv
----
SV * dbd_st_FETCH_attrib (sth, imp_sth, keysv)
SV *sth;
imp_sth_t *imp_sth;
SV *keysv;
{
STRLEN kl;
char *key = SvPV(keysv,kl);
int i, x, y, sz;
SV *retsv = Nullsv;
sql_type_info_t *type_info;
if (dbis->debug >= 4) { (void)PerlIO_printf(DBILOGFP, "dbdpg:
dbd_st_FETCH (%s) sth=%d\n", key, sth); }
/* Some can be done before the execute */
if (15==kl && strEQ(key, "pg_prepare_name")) {
retsv = newSVpv((char *)imp_sth->prepare_name, 0);
return retsv;
}
else if (17==kl && strEQ(key, "pg_server_prepare")) {
retsv = newSViv((IV)imp_sth->server_prepare);
return retsv;
}
else if (14==kl && strEQ(key, "pg_prepare_now")) {
retsv = newSViv((IV)imp_sth->prepare_now);
return retsv;
}
----
Patch for confirmed memory leak in pg_notifies:
----
*** dbdimp.c.1.49 2006-08-29 16:04:37.000000000 -0400
--- dbdimp.c 2006-08-29 16:23:32.000000000 -0400
***************
*** 832,838 ****
retsv = newRV(sv_2mortal((SV*)ret));
! return retsv;
} /* end of dbd_db_pg_notifies */
--- 832,838 ----
retsv = newRV(sv_2mortal((SV*)ret));
! return sv_2mortal(retsv);
} /* end of dbd_db_pg_notifies */