blob: 5e3d5f7f6d8a2c4e6fca49385d01a15d3d0677a5 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
#!/bin/sh
# Long-running fuzz loop per TESTING_PLAN.md's "Fuzz testing" section:
# repeatedly draw a fresh random batch of setboard/go records from the full
# 200k-position tests/cross_sectional_200k.ep_ pool, run them through a
# DEBUG=1 build under gdb (so any assert/SIGTRAP/SIGSEGV leaves a full
# backtrace instead of just a bare crash), shallow-depth, small/no hash
# (setboard memsets the hash table as a side effect, so a large --hash
# wastes time on every single record), --cpus 2 to exercise split.c's
# parallel search path too. Runs until stopped (^C) or a crash is found.
#
# Usage: ./fuzz_test.sh [binary] [depth] [batch_size] [cpus]
BIN="${1:-./_typhoon}"
DEPTH="${2:-6}"
BATCH="${3:-200}"
CPUS="${4:-2}"
SUITE=../tests/cross_sectional_200k.ep_
LOGDIR=/usr/local/tmp/typhoon/fuzz
mkdir -p "$LOGDIR"
if [ ! -x "$BIN" ]; then
echo "ERROR: $BIN not found/executable (build first: gmake clean; gmake DEBUG=1 MP=1)"
exit 1
fi
if [ ! -f "$SUITE" ]; then
echo "ERROR: $SUITE not found (run from src/)"
exit 1
fi
TOTAL_RECORDS=$(grep -c '^go' "$SUITE")
ITER=0
while :; do
ITER=$((ITER + 1))
SAMPLE="$LOGDIR/batch_${ITER}.ep_"
awk -v k="$BATCH" -v n="$TOTAL_RECORDS" 'BEGIN { srand() }
{ sub(/\r$/, "") }
/^setboard/ { rec = $0; next }
/^go[ \t]*$/ { rec = rec "\n" $0; c++; recs[c] = rec; rec = ""; next }
rec != "" { rec = rec "\n" $0 }
END {
picked = 0
while (picked < k && picked < c) {
r = int(rand() * c) + 1
if (!(r in used)) { used[r] = 1; print recs[r]; picked++ }
}
}' "$SUITE" > "$SAMPLE"
STAMP=$(date +%Y%m%d_%H%M%S)
LOG="$LOGDIR/run_${ITER}_${STAMP}.log"
GDBOUT="$LOGDIR/run_${ITER}_${STAMP}.gdb.txt"
echo "=== iter $ITER: $BATCH positions from $SUITE (sd $DEPTH, cpus $CPUS) -> $GDBOUT ==="
gdb -q -batch \
-ex "set pagination off" \
-ex run \
-ex "bt full" \
-ex "info registers" \
--args "$BIN" --cpus "$CPUS" --hash 1m --logfile "$LOG" \
--batch --command "force; book name /nonexistent.book.bin; sd $DEPTH; script $SAMPLE" \
> "$GDBOUT" 2>&1
STATUS=$?
if grep -qE 'Program terminated with signal (SIGSEGV|SIGABRT|SIGBUS|SIGILL|SIGFPE)|Assertion failure' "$GDBOUT"; then
echo "*** CRASH/ASSERT DETECTED on iter $ITER -- see $GDBOUT ***"
echo " positions: $SAMPLE"
echo " engine log: $LOG"
exit 1
fi
echo " iter $ITER clean (exit=$STATUS)"
done
|