blob: 389b0b84752d4d8bdff09fa39ba9aa6fc7ef57b4 (
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
#!/bin/bash
# Test that perf report includes file offsets and event type names in diagnostic messages.
# SPDX-License-Identifier: GPL-2.0
#
# The file_offset diagnostic series adds "at offset 0x...: TYPE (N)"
# to all skip/stop/error messages. This test corrupts an event's size
# field in a perf.data file, then verifies the resulting warning
# includes the file offset and event type.
err=0
cleanup() {
[ -n "${perfdata}" ] && rm -f "${perfdata}" "${perfdata}.old"
rm -f "${corrupted}" "${stderrfile}"
trap - EXIT TERM INT
}
trap 'cleanup; exit 1' TERM INT
trap cleanup EXIT
perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX) || exit 2
corrupted=$(mktemp /tmp/__perf_test.perf.data.XXXXX) || exit 2
stderrfile=$(mktemp /tmp/__perf_test.perf.data.XXXXX) || exit 2
if ! perf record -o "${perfdata}" -- perf test -w noploop 2>/dev/null; then
echo "Skip: perf record failed"
cleanup
exit 2
fi
# Find the file offset of the first MMAP2 event via perf report -D.
# Format: "timestamp 0xOFFSET [0xSIZE]: PERF_RECORD_MMAP2 ..."
mmap2_line=$(perf report -D -i "${perfdata}" 2>/dev/null | grep "PERF_RECORD_MMAP2" | head -1)
if [ -z "${mmap2_line}" ]; then
echo "Skip: no MMAP2 events found in perf.data"
cleanup
exit 2
fi
mmap2_offset=$(echo "${mmap2_line}" | awk '{print $2}')
mmap2_offset_dec=$((mmap2_offset))
# Copy the file and corrupt the MMAP2 event's size field.
# perf_event_header layout: type(u32) misc(u16) size(u16)
# Set size to 16 — below the MMAP2 minimum, which triggers
# the "event size too small" warning.
#
# perf.data uses native byte order, so write the u16 in the
# host's endianness to work on both LE and BE architectures.
cp "${perfdata}" "${corrupted}"
if printf '\x01\x02' | od -A n -t x2 | grep -q "0201"; then
# Little-endian
printf '\x10\x00'
else
# Big-endian
printf '\x00\x10'
fi | dd of="${corrupted}" bs=1 seek=$((mmap2_offset_dec + 6)) conv=notrunc 2>/dev/null
perf report -i "${corrupted}" --stdio > /dev/null 2> "${stderrfile}"
# Check that warnings include "at offset 0x..."
if grep -q "at offset 0x" "${stderrfile}"; then
echo "File offset in diagnostics [Success]"
else
echo "File offset in diagnostics [Failed: no 'at offset 0x...' found]"
echo " stderr was:"
head -5 "${stderrfile}"
err=1
fi
# Check that the event type name and numeric id appear: "MMAP2 (10)"
if grep -q "MMAP2 (10)" "${stderrfile}"; then
echo "Event type name in diagnostics [Success]"
else
echo "Event type name in diagnostics [Failed: no 'MMAP2 (10)' found]"
echo " stderr was:"
head -5 "${stderrfile}"
err=1
fi
# Check that the reported offset matches the actual corruption point
if grep -q "at offset ${mmap2_offset}:" "${stderrfile}"; then
echo "Correct offset reported [Success]"
else
echo "Correct offset reported [Failed: expected offset ${mmap2_offset}]"
echo " stderr was:"
head -5 "${stderrfile}"
err=1
fi
cleanup
exit ${err}
|