Copy from shells/ksh based on submit request 17433 from user WernerFink OBS-URL: https://build.opensuse.org/request/show/17433 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/ksh?expand=0&rev=31
147 lines
4.4 KiB
Plaintext
147 lines
4.4 KiB
Plaintext
| Bug bnc#520598 : memory leak in ksh
|
|
|
|
|
| From: David Korn <dgk@research.att.com>
|
|
| Subject: Re: Re: [ast-developers] Re: Memory leak in ksh upto 2009-06-30
|
|
|
|
|
| I started looking at this before I went on vacation. Here are changes
|
|
| I makde to sh/nvdisc.c that eliminate much of the problem.
|
|
| Note, that line numbers differ because my version doesn't have
|
|
| the copyright notices.
|
|
|
|
|
--- src/cmd/ksh93/sh/nvdisc.c
|
|
+++ src/cmd/ksh93/sh/nvdisc.c 2009-07-09 18:57:02.000000000 +0200
|
|
@@ -573,13 +573,14 @@ Namfun_t *nv_clone_disc(register Namfun_
|
|
{
|
|
register Namfun_t *nfp;
|
|
register int size;
|
|
+ if(!fp->disc && !fp->next && (fp->nofree&1))
|
|
+ return(fp);
|
|
if(!(size=fp->dsize) && (!fp->disc || !(size=fp->disc->dsize)))
|
|
size = sizeof(Namfun_t);
|
|
if(!(nfp=newof(NIL(Namfun_t*),Namfun_t,1,size-sizeof(Namfun_t))))
|
|
return(0);
|
|
memcpy(nfp,fp,size);
|
|
- if(flags&NV_COMVAR)
|
|
- nfp->nofree &= ~1;
|
|
+ nfp->nofree &= ~1;
|
|
nfp->nofree |= (flags&NV_RDONLY)?1:0;
|
|
return(nfp);
|
|
}
|
|
|
|
|
| From: David Korn <dgk@research.att.com>
|
|
| Subject: Re: Re: [ast-developers] Re: Memory leak in ksh upto 2009-06-30
|
|
|
|
|
| This change eliminates about 80% of the leak in the case that you sent.
|
|
| I will send another change to eliminate the rest.
|
|
|
|
|
--- src/cmd/ksh93/sh/xec.c
|
|
+++ src/cmd/ksh93/sh/xec.c 2009-08-06 18:07:12.000000000 +0200
|
|
@@ -352,7 +352,12 @@ static void put_level(Namval_t* np,const
|
|
int16_t level, oldlevel = (int16_t)nv_getnum(np);
|
|
nv_putv(np,val,flags,fp);
|
|
if(!val)
|
|
+ {
|
|
+ fp = nv_stack(np, NIL(Namfun_t*));
|
|
+ if(fp && !fp->nofree)
|
|
+ free((void*)fp);
|
|
return;
|
|
+ }
|
|
level = nv_getnum(np);
|
|
if(level<0 || level > lp->maxlevel)
|
|
{
|
|
|
|
|
| From: David Korn <dgk@research.att.com>
|
|
| Subject: Re: Re: [ast-developers] Re: Memory leak in ksh upto 2009-06-30
|
|
|
|
|
| Here is another fix that should eliminate the leak from the
|
|
| script that you sent.
|
|
|
|
|
--- src/cmd/ksh93/bltins/read.c
|
|
+++ src/cmd/ksh93/bltins/read.c 2009-08-06 19:00:24.000000000 +0200
|
|
@@ -67,9 +67,14 @@ int b_read(int argc,char *argv[], void *
|
|
int save_prompt, fixargs=((Shbltin_t*)extra)->invariant;
|
|
struct read_save *rp;
|
|
static char default_prompt[3] = {ESC,ESC};
|
|
+ rp = (struct read_save*)(((Shbltin_t*)extra)->data);
|
|
if(argc==0)
|
|
+ {
|
|
+ if(rp)
|
|
+ free((void*)rp);
|
|
return(0);
|
|
- if(rp = (struct read_save*)(((Shbltin_t*)extra)->data))
|
|
+ }
|
|
+ if(rp)
|
|
{
|
|
flags = rp->flags;
|
|
timeout = rp->timeout;
|
|
|
|
|
| From: David Korn <dgk@research.att.com>
|
|
| Subject: Re: Re: [ast-developers] Re: Memory leak in ksh upto 2009-06-30
|
|
|
|
|
| I hope that I finally got it. Here are the changes to init.c and subshell.c
|
|
|
|
|
--- src/cmd/ksh93/sh/init.c
|
|
+++ src/cmd/ksh93/sh/init.c 2009-08-10 16:05:02.000000000 +0200
|
|
@@ -445,10 +445,18 @@ static void put_cdpath(register Namval_t
|
|
static void put_ifs(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
|
|
{
|
|
register struct ifs *ip = (struct ifs*)fp;
|
|
+ Shell_t *shp;
|
|
ip->ifsnp = 0;
|
|
+ if(!val)
|
|
+ {
|
|
+ fp = nv_stack(np, NIL(Namfun_t*));
|
|
+ if(fp && !fp->nofree)
|
|
+ free((void*)fp);
|
|
+ }
|
|
if(val != np->nvalue.cp)
|
|
nv_putv(np, val, flags, fp);
|
|
-
|
|
+ if(!val && !(flags&NV_CLONE) && (fp=np->nvfun) && !fp->disc && (shp=(Shell_t*)(fp->last)))
|
|
+ nv_stack(np,&((Init_t*)shp->init_context)->IFS_init.hdr);
|
|
}
|
|
|
|
/*
|
|
@@ -522,7 +530,7 @@ static void put_seconds(register Namval_
|
|
fp = nv_stack(np, NIL(Namfun_t*));
|
|
if(fp && !fp->nofree)
|
|
free((void*)fp);
|
|
- nv_unset(np);
|
|
+ nv_putv(np, val, flags, fp);
|
|
return;
|
|
}
|
|
if(!np->nvalue.dp)
|
|
--- src/cmd/ksh93/sh/subshell.c
|
|
+++ src/cmd/ksh93/sh/subshell.c 2009-08-10 16:05:19.000000000 +0200
|
|
@@ -254,7 +254,7 @@ Namval_t *sh_assignok(register Namval_t
|
|
Namarr_t *ap;
|
|
int save;
|
|
/* don't bother with this */
|
|
- if(!sp->shpwd || (nv_isnull(np) && !add))
|
|
+ if(!sp->shpwd || (nv_isnull(np) && !add) || np==SH_LEVELNOD)
|
|
return(np);
|
|
/* don't bother to save if in newer scope */
|
|
if(!(rp=shp->st.real_fun) || !(dp=rp->sdict))
|
|
@@ -334,7 +334,7 @@ static void nv_restore(struct subshell *
|
|
continue;
|
|
if(nv_isarray(mp))
|
|
nv_putsub(mp,NIL(char*),ARRAY_SCAN);
|
|
- _nv_unset(mp,NV_RDONLY);
|
|
+ _nv_unset(mp,NV_RDONLY|NV_CLONE);
|
|
if(nv_isarray(np))
|
|
{
|
|
nv_clone(np,mp,NV_MOVE);
|
|
@@ -346,7 +346,11 @@ static void nv_restore(struct subshell *
|
|
mp->nvfun = np->nvfun;
|
|
mp->nvflag = np->nvflag;
|
|
if(nv_cover(mp))
|
|
- nv_putval(mp, nv_getval(np),0);
|
|
+ {
|
|
+ nv_putval(mp, nv_getval(np),np->nvflag|NV_NOFREE);
|
|
+ if(!nv_isattr(np,NV_NOFREE))
|
|
+ nv_offattr(mp,NV_NOFREE);
|
|
+ }
|
|
else
|
|
mp->nvalue.cp = np->nvalue.cp;
|
|
np->nvfun = 0;
|