mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Fix crash while handling subshell trap (rhbz#1117404)
Contrary to the RH bug report, this is yet another bug with
virtual/non-forked subshells and has nothing to do with functions.
If a signal is ignored (empty trap) in the main shell while any
trap (empty or not) is set on the same signal in a subshell, a
crash eventually occurred upon restoring state when leaving the
subshell.
Original patch:
642af4d6/f/ksh-20120801-trapcom.patch
Prior discussion:
https://bugzilla.redhat.com/1117404
Paulo Andrade wrote there:
> The problem is that the sh_subshell function was saving pointers
> that could change, and when restoring, bad things would happen.
[...]
> The only comment I added:
> /* contents of shp->st.trapcom may change */
> may be a bit misleading, the "bad" save/restore already knows it,
> probably I should have added a better description telling that the
> data is, usually, modified in code like:
>
> tmp = buf[i]; buf[i] = strdup(tmp); free(tmp);
>
> so the shp->st.trapcom needs a "deep copy", as done in the
> patch, to properly save/restore pointers.
src/cmd/ksh93/sh/subshell.c,
src/cmd/ksh93/sh/xec.c:
- sh_subshell(), sh_funscope(): Make *savsig/*savstak into a
**savsig array. Use strdup(3) to save the data and get known
pointers that will not change. Free these upon restore.
- Change the comment from the patch as Paulo wished he had done.
src/cmd/ksh93/tests/subshell.sh:
- Test 2500 times. This should trigger the crash most of the time.
This commit is contained in:
parent
045fe6a110
commit
6193c6a3c5
3 changed files with 63 additions and 14 deletions
|
@ -847,5 +847,19 @@ actual=${ get_value; }
|
|||
actual=`get_value`
|
||||
[[ $actual == "$expect" ]] || err_exit "\`Comsub\` failed to return output (expected '$expect', got '$actual')"
|
||||
|
||||
# ======
|
||||
# https://bugzilla.redhat.com/1117404
|
||||
|
||||
cat >$tmp/crash_rhbz1117404.ksh <<-'EOF'
|
||||
trap "" HUP # trigger part 1: signal ignored in main shell
|
||||
i=0
|
||||
for((i=0; i<2500; i++))
|
||||
do (trap ": foo" HUP) # trigger part 2: any trap (empty or not) on same signal in subshell
|
||||
done
|
||||
EOF
|
||||
got=$( { "$SHELL" "$tmp/crash_rhbz1117404.ksh"; } 2>&1)
|
||||
((!(e = $?))) || err_exit 'crash while handling subshell trap' \
|
||||
"(got status $e$( ((e>128)) && print -n / && kill -l "$e"), $(printf %q "$got"))"
|
||||
|
||||
# ======
|
||||
exit $((Errors<125?Errors:125))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue