Please submit as a context diff (made with diff -c) and send it to the -patches list, rather than -hackers.
cheers
andrew
[EMAIL PROTECTED] wrote:
In plperl.c, there are some memory leaks, fixed in the following diff file. Becuase Perl_eval_pv doesnot release stack, repitition of calling 'plperl_trigger_build_args' makes stack growing up.
The next simple example exhaust memory:(using perl v5.8.0) while (1) { AV *av = newAV(); av_undef(av); }. I cannot understand the behavior of AV, so, plperl_get_keys, plperl_get_key, and plperl_get_elem are deleted, and simply implemented by hv_iter* inlined in the loop.
Tetsuya.
diff plperl.c plperl.c.org
236,237c236
< SV *rv = NULL;
< SV *ret = NULL;
---
SV *rv;239d237
< char *s;
305,309c303
< ENTER;
< SAVETMPS;
< ret = newSVsv (perl_eval_pv(SvPV(rv, PL_na), TRUE));
< FREETMPS;
< LEAVE;
---
rv = perl_eval_pv(SvPV(rv, PL_na), TRUE);312d305
< SvREFCNT_dec(rv);
314c307
< return ret;
---
return rv;320a314,316
char *key;325,326c321
I32 klen;
SV *val;
< hv_iterinit(hv);
< while (hv_iternext(hv)){
---
while (val = hv_iternextsv(hv, (char**)&key, &klen)){332a328,371
363a403static AV* plperl_get_keys(HV* hv) { AV *ret; SV **svp; int key_count; SV *val; char *key; I32 klen; key_count = 0; ret = newAV(); while (val = hv_iternextsv(hv, (char**)&key, &klen)){ av_store(ret, key_count, eval_pv(key, TRUE)); key_count++; } return ret; }
static char* plperl_get_key(AV* keys, int index) { SV **svp; int av_len; av_len = av_len(keys)+1; if (index < av_len) svp = av_fetch(keys, index, FALSE); else return NULL; return SvPV(*svp, PL_na); }
static char* plperl_get_elem(HV* hash, char* key) { SV **svp; if (hv_exists_ent(hash, eval_pv(key, TRUE), FALSE)) svp = hv_fetch(hash, key, strlen(key), FALSE); else return NULL; return SvPV(*svp, PL_na); }
plkeys = plperl_get_keys(hvNew);382d421
< hv_iterinit(hvNew);
384a424
char *src;388,389d427
< I32 retlen;
< SV *sv;
391,396c429,430
< sv = hv_iternextsv(hvNew, &platt, &retlen);
< if (sv == NULL)
< elog(FATAL, "plperl: interpreter is probably corrupted");
< plval = SvPV(sv, PL_na);
< if (plval == NULL)
< elog(FATAL, "plperl: interpreter is probably corrupted");
---
platt = plperl_get_key(plkeys, j);403a438,440
plval = plperl_get_elem(hvNew, platt);413,428c450,455
if (plval == NULL)
elog(FATAL, "plperl: interpreter is probably corrupted");
< Oid ti;
< < ti = SPI_gettypeid(tupdesc, modattrs[j]);
< if ( ( (ti != TEXTOID) && (ti != BPCHAROID) && (ti != VARCHAROID) ) && ( (strlen(plval) == 0) || (strcmp(plval, "(null)") == 0) ) )
< {
< modvalues[j] = (Datum) 0;
< modnulls[j] = 'n';
< }
< else
< {
< modvalues[j] = FunctionCall3(&finfo,
< CStringGetDatum(plval),
< ObjectIdGetDatum(typelem),
< Int32GetDatum(tupdesc->attrs[atti]->atttypmod));
< modnulls[j] = ' ';
< }
---
src = plval;
modvalues[j] = FunctionCall3(&finfo,
CStringGetDatum(src),
ObjectIdGetDatum(typelem),
Int32GetDatum(tupdesc->attrs[atti]->atttypmod));
modnulls[j] = ' ';
877d903 < SvREFCNT_dec(svTD);
---------------------------(end of broadcast)--------------------------- TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]
---------------------------(end of broadcast)--------------------------- TIP 4: Don't 'kill -9' the postmaster