Thread: plperl: memory usage stacking

plperl: memory usage stacking

From
biz@html.ne.jp
Date:
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);


Re: plperl: memory usage stacking

From
Andrew Dunstan
Date:
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
>
>  
>


Re: plperl: memory usage stacking

From
Tom Lane
Date:
Andrew Dunstan <andrew@dunslane.net> writes:
> Please submit as a context diff (made with diff -c) and send it to the 
> -patches list, rather than -hackers.

It would also help if you'd identify what version the diff is against.
I can't match up any of this with current sources...
        regards, tom lane