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
This commit is contained in:
OBS User autobuild 2009-08-13 15:23:42 +00:00 committed by Git OBS Bridge
parent a4861746e1
commit e529961e6c
6 changed files with 332 additions and 96 deletions

View File

@ -1,3 +1,9 @@
-------------------------------------------------------------------
Tue Aug 11 11:39:45 CEST 2009 - werner@suse.de
- Add three patches from David Korn for bug bnc#520598
- Use mapping of libast virtual memory management (bnc#523212)
-------------------------------------------------------------------
Tue Aug 4 14:37:37 CEST 2009 - werner@suse.de

View File

@ -26,12 +26,14 @@ Group: System/Shells
PreReq: /bin/ln /bin/rm /etc/bash.bashrc /bin/true
AutoReqProv: on
Version: 93t
Release: 13
Release: 14
Summary: Korn Shell
BuildRoot: %{_tmppath}/%{name}-%{version}-build
Source: INIT.2009-06-30.tar.bz2
Source1: ast-ksh.2009-06-30.tar.bz2
Source2: ast-open-locale.2008-07-25.tar.bz2
Source10: leak1.sh
Source11: leak2.sh
Source20: Agreement
Source21: Warning
Source22: libast.cflags
@ -52,8 +54,10 @@ Patch12: ksh93-limits.dif
Patch14: ksh93-ia64.dif
Patch15: ksh93-s390.dif
Patch16: ksh93-memleak.dif
Patch42: ksh93-debugleaks.dif
%global use_suid_exe 0
%global use_locale 0
%global debug_memleak 0
%description
The original Korn Shell. The ksh is an sh-compatible command
@ -117,6 +121,9 @@ find share/ -type d -a -empty | xargs -r rm -vrf
%endif
%patch15
%patch16
%if %debug_memleak
%patch42
%endif
%build
# This package failed when testing with -Wl,-as-needed being default.
@ -172,6 +179,7 @@ find share/ -type d -a -empty | xargs -r rm -vrf
esac
RPM_OPT_FLAGS=$(echo "${RPM_OPT_FLAGS}"|sed -r 's/[[:blank:]]+-g[0-9]?//g')
UNIVERSE=att
LDFLAGS="-lm"
CC=gcc
cflags -std=gnu99 RPM_OPT_FLAGS
cflags -fPIC RPM_OPT_FLAGS
@ -179,9 +187,11 @@ find share/ -type d -a -empty | xargs -r rm -vrf
cflags -fno-strict-aliasing RPM_OPT_FLAGS
cflags -fno-zero-initialized-in-bss RPM_OPT_FLAGS
cflags -g RPM_OPT_FLAGS
cflags -pipe RPM_OPT_FLAGS
cflags -Wl,-O2 LDFLAGS
cflags -Wl,--hash-size=16699 LDFLAGS
RPM_OPT_FLAGS="$RPM_OPT_FLAGS -D_GNU_SOURCE $LARGEFILE"
RPM_OPT_FLAGS="$RPM_OPT_FLAGS $IGNORE $FEATURE"
LDFLAGS="-lm"
HOSTTYPE=${RPM_ARCH%%*-linux*}
mam_cc_L=use
mam_cc_OPTIMIZE=-pipe
@ -249,16 +259,25 @@ find share/ -type d -a -empty | xargs -r rm -vrf
${ksh} -Wl,-rpath-link,${root}/lib -Wl,-rpath,/%{_lib}/ast
${shcomp} -Wl,-rpath-link,${root}/lib -Wl,-rpath,/%{_lib}/ast
${suidex} -Wl,-rpath-link,${root}/lib -Wl,-rpath,/%{_lib}/ast
OPATH=$PATH
OSHELL=$SHELL
LD_LIBRARY_PATH=${root}/lib
PATH=$PATH:${root}/bin
SHELL=${root}/bin/ksh
export LD_LIBRARY_PATH PATH SHELL
pushd ${test}
sleep 5
LD_LIBRARY_PATH=${root}/lib PATH=$PATH:${root}/bin SHELL=${root}/bin/ksh ${root}/bin/ksh shtests
${root}/bin/ksh shtests
${root}/bin/ksh %{S:10}
${root}/bin/ksh %{S:11}
popd
pushd ${root}/bin
set -- $(LD_LIBRARY_PATH=${root}/lib PATH=$PATH:${root}/bin shcomp --version 2>&1)
PATH=$PATH:.
set -- $(shcomp --version 2>&1)
eval version=\${$#}
LD_LIBRARY_PATH=${root}/lib PATH=$PATH:. shcomp --nroff 2>&1 | \
sed 's/\(\.TH .*\)/\1 "2003-03-02" "" "Korn shell utilities"/' > ../man/man1/shcomp.1
shcomp --nroff 2>&1 | sed 's/\(\.TH .*\)/\1 "2003-03-02" "" "Korn shell utilities"/' > ../man/man1/shcomp.1
popd
SHELL=$OSHELL
PATH=$OPATH
popd
%install

84
ksh93-debugleaks.dif Normal file
View File

@ -0,0 +1,84 @@
--- src/lib/libast/vmalloc/malloc.c
+++ src/lib/libast/vmalloc/malloc.c 2009-08-06 10:27:36.465902620 +0000
@@ -131,13 +131,23 @@ typedef struct ______mstats Mstats_t;
#undef valloc
#endif
+#define DEBUG_LEAK 1
+#if defined(DEBUG_LEAK) && (DEBUG_LEAK > 0)
+Void_t* _global_alloc;
+Void_t* _global_free;
+#endif
+
#if _WINIX
#include <ast_windows.h>
#if _UWIN
+#if defined(DEBUG_LEAK) && (DEBUG_LEAK > 0)
+#define VMRECORD(p) (_global_alloc = _vmrecord(p))
+#else
#define VMRECORD(p) _vmrecord(p)
+#endif
#define VMBLOCK { int _vmblock = _sigblock();
#define VMUNBLOCK _sigunblock(_vmblock); }
@@ -173,7 +183,11 @@ lcl_getenv(const char* s)
#endif /* _WINIX */
#ifndef VMRECORD
+#if defined(DEBUG_LEAK) && (DEBUG_LEAK > 0)
+#define VMRECORD(p) (_global_alloc = (p))
+#else
#define VMRECORD(p) (p)
+#endif
#define VMBLOCK
#define VMUNBLOCK
#endif
@@ -496,6 +510,9 @@ extern void free(data)
reg Void_t* data;
#endif
{
+#if defined(DEBUG_LEAK) && (DEBUG_LEAK > 0)
+ _global_free = data;
+#endif
#if USE_NATIVE
#undef free
#if __STD_C
--- debug
+++ debug 2009-08-06 11:13:00.514401978 +0000
@@ -0,0 +1,33 @@
+#!/bin/sh
+tmp=$(mktemp gdbrc.XXXXXX) || exit 1
+log=$(mktemp gdblg.XXXXXX) || exit 1
+trap "rm -f $tmp $log" EXIT SIGINT
+(cat > $tmp)<<---
+ set logging file $log
+ set logging overwrite on
+ set logging redirect on
+ set logging on
+ watch _global_alloc
+ commands
+ silent
+ printf "\n alloc = %p\n ======================\n", _global_alloc
+ if sh.subshell >= 1
+ bt 12
+ end
+ cont
+ end
+ watch _global_free
+ commands
+ silent
+ printf "\n free = %p\n ======================\n", _global_free
+ cont
+ end
+ run
+ quit
+--
+env -i gdb -batch-silent -x $tmp --args ./arch/*/src/cmd/ksh93/ksh $1
+grep -E '^[[:blank:]]+alloc[[:blank:]]+=[[:blank:]]+0x' $log | \
+ while read alloc sign val; do
+ grep -qE "^[[:blank:]]+free[[:blank:]]+=[[:blank:]]+$val" $log && continue
+ sed -rn "/^[[:blank:]]+alloc[[:blank:]]+=[[:blank:]]+$val/,/^$/p" $log
+ done

View File

@ -1,102 +1,146 @@
--- src/cmd/ksh93/bltins/misc.c
+++ src/cmd/ksh93/bltins/misc.c 2009-08-04 11:59:27.525901725 +0000
@@ -276,7 +276,11 @@ int b_dot_cmd(register int n,char *ar
shp->st.cmdname = argv[0];
if(np)
shp->st.filename = np->nvalue.rp->fname;
+ if (SH_PATHNAMENOD->nvfun)
+ SH_PATHNAMENOD->nvfun->nofree |= 4;
nv_putval(SH_PATHNAMENOD, shp->st.filename ,NV_NOFREE);
+ if (SH_PATHNAMENOD->nvfun)
+ SH_PATHNAMENOD->nvfun->nofree &= ~4;
shp->posix_fun = 0;
if(np || argv[1])
argsave = sh_argnew(shp,argv,&saveargfor);
--- src/cmd/ksh93/sh/subshell.c
+++ src/cmd/ksh93/sh/subshell.c 2009-08-04 11:57:31.829902225 +0000
@@ -252,7 +252,7 @@ Namval_t *sh_assignok(register Namval_t
Dt_t *dp;
Namval_t *mpnext;
Namarr_t *ap;
- int save;
+ int save, leak;
/* don't bother with this */
if(!sp->shpwd || (nv_isnull(np) && !add))
return(np);
@@ -309,7 +309,18 @@ Namval_t *sh_assignok(register Namval_t
save = shp->subshell;
shp->subshell = 0;
mp->nvname = np->nvname;
+ leak = 0;
+ if (np->nvfun && np->nvfun->nofree&4)
+ {
+ leak = 1;
+ np->nvfun->nofree &= ~4;
+ }
nv_clone(np,mp,(add?(nv_isnull(np)?0:NV_NOFREE)|NV_ARRAY:NV_MOVE));
+ if (leak && mp->nvfun && np->nvfun != mp->nvfun)
+ {
+ free((void*)mp->nvfun);
+ mp->nvfun = np->nvfun;
+ }
shp->subshell = save;
return(np);
| 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-04 11:58:31.033901866 +0000
@@ -339,6 +339,7 @@ struct Level
Namfun_t hdr;
short maxlevel;
};
+struct Level *leaklp;
/*
* this is for a debugger but it hasn't been tested yet
@@ -352,7 +353,11 @@ static void put_level(Namval_t* np,const
+++ 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)
+ {
+ if (np == SH_LEVELNOD)
+ leaklp = (struct Level*)(SH_LEVELNOD->nvfun);
+ 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)
{
@@ -374,7 +379,22 @@ static const Namdisc_t level_disc = { s
static struct Level *init_level(int level)
|
| 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)
{
- struct Level *lp = newof(NiL,struct Level,1,0);
+ struct Level *lp;
+ if (!leaklp)
+ lp = newof(NiL,struct Level,1,0);
+ else
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)
+ {
+ if (leaklp->hdr.disc)
+ 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);
+ {
+ leaklp->hdr.disc = NIL(const Namdisc_t*);
+ lp = leaklp;
+ nv_putval(mp, nv_getval(np),np->nvflag|NV_NOFREE);
+ if(!nv_isattr(np,NV_NOFREE))
+ nv_offattr(mp,NV_NOFREE);
+ }
+ else
+ {
+ free((void*)leaklp);
+ lp = newof(NiL,struct Level,1,0);
+ }
+ }
lp->maxlevel = level;
_nv_unset(SH_LEVELNOD,0);
nv_onattr(SH_LEVELNOD,NV_INT16|NV_NOFREE);
@@ -2689,7 +2709,11 @@ static void sh_funct(Shell_t *shp,Namval
save = argv[-1];
argv[-1] = 0;
shp->st.funname = nv_name(np);
+ if (SH_FUNNAMENOD->nvfun)
+ SH_FUNNAMENOD->nvfun->nofree |= 4;
nv_putval(SH_FUNNAMENOD, nv_name(np),NV_NOFREE);
+ if (SH_FUNNAMENOD->nvfun)
+ SH_FUNNAMENOD->nvfun->nofree &= ~4;
opt_info.index = opt_info.offset = 0;
error_info.errors = 0;
shp->st.loopcnt = 0;
else
mp->nvalue.cp = np->nvalue.cp;
np->nvfun = 0;

37
leak1.sh Normal file
View File

@ -0,0 +1,37 @@
#!/usr/bin/ksh
PATH=/bin:/usr/bin:/usr/sbin:/sbin
getSampleInterval() { return 0; }
typeset -ilu times=4000
typeset -ilu leak=0
vm()
{
typeset size
typeset key unit result=""
while read key size unit; do
case "$key" in
VmSize*) result=${result:+"$result:"}$size ;;
VmRSS*) result=${result:+"$result:"}$size ;;
VmData*) result=${result:+"$result:"}$size ;;
esac
done < /proc/$$/status
echo $result
}
curstate="XXXX:XXXX:XXXX"
oldstate=$(vm)
while ((times-- > 0))
do
interval=$(getSampleInterval)
curstate=$(vm)
[ "$curstate" != "$oldstate" ] && let leak++
oldstate="$curstate"
done
echo "[${0##*/}: leak count at $leak]"
((leak < 6)) || exit 1

46
leak2.sh Normal file
View File

@ -0,0 +1,46 @@
#!/usr/bin/ksh
foo=0
LoopCountForMEMSAP=0
bla=234
typeset -lui count=4000
typeset -lui leak=0
vm()
{
typeset size
typeset key unit result=""
while read key size unit; do
case "$key" in
VmSize*) result=${result:+"$result:"}$size ;;
VmRSS*) result=${result:+"$result:"}$size ;;
VmData*) result=${result:+"$result:"}$size ;;
esac
done < /proc/$$/status
echo $result
}
fusub()
{
datun=`date +%S`
# datun=$(date +%S)
interval=$((10 - datun%10))
}
curstate="XXXX:XXXX:XXXX"
oldstate=$(vm)
while ((count-- > 0))
do
foo=$((foo+1))
datum=`fusub`
# datum=$(fusub)
curstate=$(vm)
[ "$curstate" != "$oldstate" ] && let leak++
oldstate="$curstate"
done
echo "[${0##*/}: leak count at $leak]"
((leak < 7)) || exit 1