#!/bin/sh

modulename=taskmonitor
if modprobe $modulename target="-1" 2> /dev/null; then
	echo "Should throw an error with an invalid pid"
	exit 1
fi

printf '%s' '
#include <stdlib.h>
#include <unistd.h>

#define N 40
#define M (1024 * 1024)

int main() {
	char *array = malloc(sizeof(char) * M * N);

	for (int i = 1; i < N * M; i+=4096) {
		array[i] = array[i - 1];
	}
	sleep(2);
	free(array);
	sleep(10000);
}
' > test.c

if ! gcc test.c; then
	echo "can't compile userspace program"
	exit 1
fi

./a.out &

pid=$!

sleep 1

if ! modprobe $modulename target="$pid"; then
	echo "Could not load module $modulename.ko!"
	exit 1
fi

if ! test -f /sys/kernel/taskmonitor; then
	echo "sysfs file not created!"
	exit 1
fi

sleep 4
file="/sys/kernel/taskmonitor"

first_vm_data=$(head -n 1 "$file" | awk '{print $NF}')
last_vm_data=$(tail -n 1 "$file" | awk '{print $NF}')
cat "$file"

## The commented out test below is executed by the LKP Maintainers CI.
# It checks that the 'vm_data' field is correct over a few seconds of monitoring.
# The expected values have been replaced in this commented out code by HIDDEN.
# The expected output is supposed to show a higher value for the first lines of monitoring because of the big malloc in the test.c program above, and then to decrease because of the free.
# The expected order of the logs is chronological.

# check that the vm_data field is correct
# if awk '{print $NF}' "$file" | grep -vE '^(HIDDEN)$' > /dev/null; then
#     echo "The vm_data field is wrong!"
# 	exit 1
# fi
#
# if [ "$first_vm_data" != "HIDDEN" ] && [ "$first_vm_data" != "HIDDEN" ]; then
# 	if [ "$last_vm_data" = "HIDDEN" ] || [ "$last_vm_data" = "HIDDEN" ]; then
# 		echo "You are printing logs upside down!"
# 		exit 1
# 	else
# 		echo "The vm_data field is wrong $first_vm_data"
# 		exit 1
# 	fi
# fi
# if [ "$last_vm_data" != "HIDDEN" ] && [ "$last_vm_data" != "HIDDEN" ]; then
#     echo "The vm_data field is wrong $last_vm_data"
# 	exit 1
# fi

if ! rmmod $modulename; then
	echo "Fail while unloading module"
	exit 1
fi

echo scan > /sys/kernel/debug/kmemleak
sleep 60
cat /sys/kernel/debug/kmemleak
