ksh/ksh93-memleak.dif
OBS User autobuild e529961e6c Accepting request 17433 from shells
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
2009-08-13 15:23:42 +00:00

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;