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
|
||||
|
||||
[[ -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
|
||||
{
|
||||
vmstate --format='%(busy_size)u'
|
||||
}
|
||||
n=$(getmem)
|
||||
if ! let "($n) == ($n) && n > 0" # not a non-zero number?
|
||||
then err\_exit "$LINENO" "vmstate built-in command not functioning; tests cannot be run"
|
||||
exit 1
|
||||
|
||||
# Determine method for running tests.
|
||||
# The 'vmstate' builtin can be used if ksh was compiled with vmalloc.
|
||||
if builtin vmstate 2>/dev/null &&
|
||||
n=$(vmstate --format='%(busy_size)u') &&
|
||||
let "($n) == ($n) && n > 0" # non-zero number?
|
||||
then N=512 # number of iterations for each test
|
||||
unit=bytes
|
||||
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
|
||||
|
||||
# test for variable reset leak #
|
||||
|
@ -57,18 +73,13 @@ function test_reset
|
|||
# Initialise variables used below to avoid false leaks
|
||||
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
|
||||
# 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.
|
||||
#
|
||||
# Check results.
|
||||
# The function has 'err_exit' in the name so that shtests counts each call as at test.
|
||||
function err_exit_if_leak
|
||||
{
|
||||
if ((after > before + 2 * N))
|
||||
then err\_exit "$1" "$2 (leaked $((after - before)) bytes after $N iterations)"
|
||||
if ((after > before + tolerance))
|
||||
then err\_exit "$1" "$2 (leaked approx $((after - before)) $unit after $N iterations)"
|
||||
fi
|
||||
}
|
||||
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';))"
|
||||
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)
|
||||
for ((i=0; i < N; i++))
|
||||
do print -r -- "$data"
|
||||
|
@ -109,7 +123,6 @@ for ((i=0; i < N; i++))
|
|||
do read -C stat <<< "$data"
|
||||
done
|
||||
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 <<<"
|
||||
|
||||
# ======
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue