Please submit as a context diff (made with diff -c) and send it to the
-patches list, rather than -hackers.
cheers
andrew
biz@html.ne.jp 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;
>> I32 klen;
>> SV *val;
>>
>>
>325,326c321
>< hv_iterinit(hv);
>< while (hv_iternext(hv)){
>---
>
>
>> while (val = hv_iternextsv(hv, (char**)&key, &klen)){
>>
>>
>332a328,371
>
>
>>static
>>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);
>>}
>>
>>
>>
>363a403
>
>
>> 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);
>> if (plval == NULL)
>> elog(FATAL, "plperl: interpreter is probably corrupted");
>>
>>
>413,428c450,455
>< 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 majordomo@postgresql.org
>
>
>