File: kill-on-exit.sh

package info (click to toggle)
strace 6.13%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 71,488 kB
  • sloc: ansic: 176,497; sh: 9,675; makefile: 4,133; cpp: 885; awk: 353; perl: 267; exp: 62; sed: 9
file content (94 lines) | stat: -rwxr-xr-x 2,208 bytes parent folder | download | duplicates (6)
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/bin/sh
#
# Check that PTRACE_O_EXITKILL is set properly.
#
# Copyright (c) 2023 Dmitry V. Levin <ldv@strace.io>
# All rights reserved.
#
# SPDX-License-Identifier: GPL-2.0-or-later

max_wait_attempts=100

$STRACE -d -f $kill_on_exit_option -e trace=fchdir / > /dev/null 2> "$LOG" ||:
if grep -x "[^:]*strace: PTRACE_O_EXITKILL does not work" "$LOG" > /dev/null; then
	skip_ 'PTRACE_O_EXITKILL does not work'
fi
grep -x "[^:]*strace: PTRACE_O_EXITKILL works" "$LOG" > /dev/null ||
        fail_ 'PTRACE_O_EXITKILL marker not found'

check_prog sed
run_prog_skip_if_failed \
	kill -0 $$

cat >script <<EOF
#!/bin/sh -efu
trap '' TERM
echo ONE
# Do not wait forever, stop waiting after a few iterations.
attempt=0
while [ "\$attempt" -lt "$max_wait_attempts" ] && [ ! -s 'killed' ]; do
        $SLEEP_A_BIT
        attempt=\$((attempt + 1))
done
[ -s 'killed' ] || {
	echo TIMEOUT
	exit 1
}
echo TWO
EOF
chmod +x script

run_tracer()
{
	local attempt expected_rc tracee_pid tracer_pid rc=0
	expected_rc="$1"; shift

	> "$OUT"
	> killed

	$STRACE -d -D -I2 -f -e/exit "$@" ./script > "$OUT" 2> "$LOG" &
	tracee_pid=$!

	# Do not wait forever, stop waiting after a few iterations.
	attempt=0
	while [ "$attempt" -lt "$max_wait_attempts" ] && [ ! -s "$OUT" ]; do
		$SLEEP_A_BIT
		attempt=$((attempt + 1))
	done
	[ -s "$OUT" ] ||
		fail_ 'timeout waiting for the script output'

	tracer_pid=$(sed -n 's/^[^:]*strace: new tracer pid is \([[:digit:]]\+\)$/\1/p' "$LOG")
	[ -n "$tracer_pid" ] || {
		kill -9 $tracee_pid
		fail_ 'tracer pid not found'
	}
	kill $tracer_pid

	# Do not wait forever, stop waiting after a few iterations.
	attempt=0
	while [ "$attempt" -lt "$max_wait_attempts" ] && kill -0 "$tracer_pid" 2> /dev/null; do
		$SLEEP_A_BIT
		attempt=$((attempt + 1))
	done
	[ "$attempt" -lt "$max_wait_attempts" ] ||
		fail_ 'timeout waiting for the tracer to terminate'

	echo > killed
	wait $tracee_pid ||
		rc=$?
	[ "$rc" = "$expected_rc" ] ||
		fail_ "expected rc $expected_rc, got rc $rc"
	match_diff "$OUT" "$EXP"
}

# first time without $kill_on_exit_option
{
	echo ONE
	echo TWO
} > "$EXP"
run_tracer 0

# second time with $kill_on_exit_option
echo ONE > "$EXP"
run_tracer 137 $kill_on_exit_option