#!/bin/sh
# DF-5624 decisive loop (v2 rig, used for BOTH baseline and fixed runs):
# kldload the PoC in fresh processes (each gets a new kstack / new
# neighbour).  The module prints NEIGHBOR MAPPED|UNMAPPED per load.
#
#   BASELINE (buggy kernel): the first UNMAPPED load panics the box
#     (fatal trap 12 in hard_sniff+0x9e == mp_flame.c:138) -- the loop
#     and ssh die with the guest; serial console holds the panic.
#   FIXED kernel: loop completes; UNMAPPED loads SURVIVE; no panic;
#     dump shows all rips[1]=0 (guard refuses rbp==top-8).
N=0
MAX=${ITERS:-150}
UNMAPPED=0
sysctl -w debug.flame_graph_enable=1 >/dev/null
while [ $N -lt $MAX ]; do
	N=$((N + 1))
	sh -c "kldload /root/df5624/flameoob.ko; kldunload flameoob" >/dev/null 2>&1 || {
		echo "=== iteration $N: kldload FAILED (guest dying?) ==="
		break
	}
	U=$(dmesg | grep -c "DF5624: NEIGHBOR UNMAPPED")
	if [ "$U" -gt "$UNMAPPED" ]; then
		UNMAPPED=$U
		echo "=== iteration $N: survived UNMAPPED neighbour #$U ==="
	fi
done
sysctl -w debug.flame_graph_enable=0 >/dev/null
echo "=== loop completed $N iterations, $UNMAPPED unmapped-neighbour survivals ==="
echo "=== neighbour summary this boot ==="
dmesg | grep "DF5624: NEIGHBOR" | sort | uniq -c
echo "=== final flame entry dump (all rips[1] must be 0 on fixed kernel) ==="
/root/df5624/flame_dump | grep FOUND | grep -v "rips\[1\]=0000000000000000"
/root/df5624/flame_dump | tail -1
