File ksh93-memleak.dif of Package ksh

| 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;
openSUSE Build Service is sponsored by