1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

Fix crash upon running many subshells (#113)

Co-authored-by: Martijn Dekker <martijn@inlv.org>

An intermittent crash occurred after running many thousands of
virtual/non-forked subshells. One reproducer is a crash in the
shbench fibonacci.ksh test, as documented here:
f3d9e134/bench/fibonacci.ksh (L4-L10)

The apparent cause was the signed and insufficiently large 'short'
data type of 'curenv' and related variables which wrapped around to
a negative number when overflowing. These IDs are necessary for the
'wait' builtin to obtain the exit status from a background job.

This fix is inspired by a patch based on ksh 93v-:
https://build.opensuse.org/package/view_file/shells/ksh/ksh93-longenv.dif?expand=1
https://src.fedoraproject.org/rpms/ksh/blob/f24/f/ksh-20130628-longer.patch

However, we change the type to 'unsigned int' instead of 'long'. On
all remotely modern systems, ints are 32-bit values, and using this
type avoids a performance degradation on 32-bit sytems. Making them
unsigned prevents an overflow to negative values.

src/cmd/ksh93/include/defs.h,
src/cmd/ksh93/include/jobs.h,
src/cmd/ksh93/include/nval.h,
src/cmd/ksh93/include/shell.h:
- Change the types of the static global 'subenv' and the subshell
  structure members 'curenv', 'jobenv', 'subenv', 'p_env' and
  'subshell' to one consistent type, unsigned int.

src/cmd/ksh93/sh/jobs.c,
src/cmd/ksh93/sh/macro.c:
src/cmd/ksh93/sh/name.c:
src/cmd/ksh93/sh/nvtype.c,
src/cmd/ksh93/sh/subshell.c:
- Updates to match new variable types.

src/cmd/ksh93/tests/subshell.sh:
- Show wrong exit status in message on failure of 'wait' builtin.
This commit is contained in:
Johnothan King 2020-08-12 10:50:59 -07:00 committed by GitHub
parent f485fe0f8d
commit 05ac1dbb41
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 25 additions and 17 deletions

View file

@ -103,7 +103,7 @@ static struct subshell
char pwdclose;
} *subshell_data;
static int subenv;
static unsigned int subenv;
/*
@ -176,7 +176,7 @@ void sh_subfork(void)
{
register struct subshell *sp = subshell_data;
Shell_t *shp = sp->shp;
int curenv = shp->curenv;
unsigned int curenv = shp->curenv;
pid_t pid;
char *trap = shp->st.trapcom[0];
if(trap)
@ -251,7 +251,7 @@ Namval_t *sh_assignok(register Namval_t *np,int add)
Dt_t *dp= shp->var_tree;
Namval_t *mpnext;
Namarr_t *ap;
int save;
unsigned int save;
/* don't bother to save if in a ${ subshare; } */
if(sp->subshare)
return(np);
@ -456,7 +456,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
struct subshell sub_data;
register struct subshell *sp = &sub_data;
int jmpval,nsig=0,duped=0;
int savecurenv = shp->curenv;
unsigned int savecurenv = shp->curenv;
int savejobpgid = job.curpgid;
int *saveexitval = job.exitval;
char *savsig;