mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
tests/leaks.sh: allow run without vmalloc/vmstate
This allows running 'bin/shtests leaks' on a ksh without the vmstate builtin and/or that is not compiled with AST vmalloc. It falls back to 'ps -o rss= -p $$' to get the memory state. This is in preparation for the beta and release versions, which will not use vmalloc due to its defects[*]. Unfortunately, abandoning vmalloc means abandoning the vmstate builtin which makes it extremely efficient to test for memory leaks. Because 'ps' only has a KiB granularity and also shows larger artefacts/variations than vmalloc on most systems, we need many more iterations (16384) and also tolerate a higher number of bytes per iterations (8). So the run takes much longer. To tolerate only 2 bytes per iteration, we would need four times as many iterations, which would make it take too long to run. Since a single word (e.g. one pointer) on a 64-bit system is 8 bytes, it still seems very unlikely for a real memory leak to be that small. This is coded to make it easy to detect and add iteration and tolerance parameters for a new method to get the memory state, if some efficient or precise system-specific way is discovered. I've also managed to trigger a false leak with shcomp in a UTF-8 locale on CentOS on a ksh with vmalloc/vmstate. So this increases the tolerance for vmalloc from 2 to 4 bytes/iteration. [*] Discussion: https://github.com/ksh93/ksh/issues/95
This commit is contained in:
parent
69679be8d7
commit
fbdf240acb
1 changed files with 32 additions and 19 deletions
|
@ -30,17 +30,33 @@ Command=${0##*/}
|
||||||
integer Errors=0
|
integer Errors=0
|
||||||
|
|
||||||
[[ -d $tmp && -w $tmp && $tmp == "$PWD" ]] || { err\_exit "$LINENO" '$tmp not set; run this from shtests. Aborting.'; exit 1; }
|
[[ -d $tmp && -w $tmp && $tmp == "$PWD" ]] || { err\_exit "$LINENO" '$tmp not set; run this from shtests. Aborting.'; exit 1; }
|
||||||
builtin vmstate 2>/dev/null || { err\_exit "$LINENO" 'vmstate built-in command not compiled in; skipping tests'; exit 0; }
|
|
||||||
|
|
||||||
# Get the current amount of memory usage
|
|
||||||
function getmem
|
# Determine method for running tests.
|
||||||
{
|
# The 'vmstate' builtin can be used if ksh was compiled with vmalloc.
|
||||||
vmstate --format='%(busy_size)u'
|
if builtin vmstate 2>/dev/null &&
|
||||||
}
|
n=$(vmstate --format='%(busy_size)u') &&
|
||||||
n=$(getmem)
|
let "($n) == ($n) && n > 0" # non-zero number?
|
||||||
if ! let "($n) == ($n) && n > 0" # not a non-zero number?
|
then N=512 # number of iterations for each test
|
||||||
then err\_exit "$LINENO" "vmstate built-in command not functioning; tests cannot be run"
|
unit=bytes
|
||||||
exit 1
|
tolerance=$((4*N)) # tolerate 4 bytes per iteration to account for vmalloc artefacts
|
||||||
|
function getmem
|
||||||
|
{
|
||||||
|
vmstate --format='%(busy_size)u'
|
||||||
|
}
|
||||||
|
# Otherwise, make do with the nonstandard 'rss' (real resident size) keyword
|
||||||
|
# of the 'ps' command (the standard 'vsz', virtual size, is not usable).
|
||||||
|
elif n=$(ps -o rss= -p "$$" 2>/dev/null) &&
|
||||||
|
let "($n) == ($n) && n > 0"
|
||||||
|
then N=16384
|
||||||
|
unit=KiB
|
||||||
|
tolerance=$((8*N/1024)) # tolerate 8 bytes per iteration to account for malloc/ps artefacts
|
||||||
|
function getmem
|
||||||
|
{
|
||||||
|
ps -o rss= -p "$$"
|
||||||
|
}
|
||||||
|
else err\_exit "$LINENO" 'WARNING: cannot find method to measure memory usage; skipping tests'
|
||||||
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# test for variable reset leak #
|
# test for variable reset leak #
|
||||||
|
@ -57,18 +73,13 @@ function test_reset
|
||||||
# Initialise variables used below to avoid false leaks
|
# Initialise variables used below to avoid false leaks
|
||||||
before=0 after=0 i=0 u=0
|
before=0 after=0 i=0 u=0
|
||||||
|
|
||||||
# Number of iterations for each test
|
|
||||||
N=512
|
|
||||||
|
|
||||||
# Check results. Add a tolerance of 2 bytes per iteration. Some tests appear to have tiny leaks, but they
|
# Check results.
|
||||||
# must be vmalloc artefacts; they may increase with the number of iterations, then suddenly go away when the
|
|
||||||
# number of iterations is large enough (e.g. 10000) and don't return when increasing iterations further.
|
|
||||||
#
|
|
||||||
# The function has 'err_exit' in the name so that shtests counts each call as at test.
|
# The function has 'err_exit' in the name so that shtests counts each call as at test.
|
||||||
function err_exit_if_leak
|
function err_exit_if_leak
|
||||||
{
|
{
|
||||||
if ((after > before + 2 * N))
|
if ((after > before + tolerance))
|
||||||
then err\_exit "$1" "$2 (leaked $((after - before)) bytes after $N iterations)"
|
then err\_exit "$1" "$2 (leaked approx $((after - before)) $unit after $N iterations)"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
alias err_exit_if_leak='err_exit_if_leak "$LINENO"'
|
alias err_exit_if_leak='err_exit_if_leak "$LINENO"'
|
||||||
|
@ -91,6 +102,9 @@ done
|
||||||
|
|
||||||
data="(v=;sid=;di=;hi=;ti='1328244300';lv='o';id='172.3.161.178';var=(k='conn_num._total';u=;fr=;l='Number of Connections';n='22';t='number';))"
|
data="(v=;sid=;di=;hi=;ti='1328244300';lv='o';id='172.3.161.178';var=(k='conn_num._total';u=;fr=;l='Number of Connections';n='22';t='number';))"
|
||||||
read -C stat <<< "$data"
|
read -C stat <<< "$data"
|
||||||
|
for ((i=0; i < 8; i++)) # steady state first
|
||||||
|
do print -r -- "$data" | while read -u$n -C stat; do :; done {n}<&0-
|
||||||
|
done
|
||||||
before=$(getmem)
|
before=$(getmem)
|
||||||
for ((i=0; i < N; i++))
|
for ((i=0; i < N; i++))
|
||||||
do print -r -- "$data"
|
do print -r -- "$data"
|
||||||
|
@ -109,7 +123,6 @@ for ((i=0; i < N; i++))
|
||||||
do read -C stat <<< "$data"
|
do read -C stat <<< "$data"
|
||||||
done
|
done
|
||||||
after=$(getmem)
|
after=$(getmem)
|
||||||
# this test can show minor variations in memory usage when run with shcomp: https://github.com/ksh93/ksh/issues/70
|
|
||||||
err_exit_if_leak "memory leak with read -C when using <<<"
|
err_exit_if_leak "memory leak with read -C when using <<<"
|
||||||
|
|
||||||
# ======
|
# ======
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue