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 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
|
#!/bin/sh
# PCP QA Test No. 1705
# Exercise the bpftrace PMDA - error conditions
#
seq=`basename $0`
echo "QA output created by $seq"
. ./common.bpftrace
case `admin/whatami`
in
*openSUSE\ Leap\ 15.*)
_notrun "this test does not work on openSUSE 15.x"
;;
esac
_pmdabpftrace_check
echo "tracepoint:raw_syscalls:sys_enter" >$tmp.tmp
_pmdabpftrace_check_probes $tmp.tmp
case `hostname -s`
in
bozo-vm)
_notrun "cannot set bpftrace hz=999 on this VM"
;;
esac
status=1 # failure is the default!
_prepare_pmda bpftrace
trap "_pmdabpftrace_cleanup; exit \$status" 0 1 2 3 15
_stop_auto_restart pmcd
_filter_exit_code()
{
# some versions of bpftrace exit with different codes
sed -e 's/ value -6$/ value 1/g'
}
# names of first 512 d* kprobes are not deterministic ...
#
# bpftrace.control.register old value="{}" new value="// name: test4
# kprobe:d3cold_allowed_show { @c = count(); }
# kprobe:d3cold_allowed_store { @c = count(); }
# ...
# kprobe:debugfs_write_file_bool { @c = count(); }
# kprobe:debugfs_write_file_str { @c = count(); }"
#
_filter_kprobe()
{
$PCP_AWK_PROG '
!/^kprobe:/ { print; next }
{ print "kprobe:... { @c = count(); }"
print "..."
print "kprobe:... { @c = count(); }\""
exit
}'
}
# this shoud be the default, just to be sure, to be sure, ...
#
BPFTRACE_MAX_PROBES=512; export BPFTRACE_MAX_PROBES
# real QA test starts here
cat <<EOF | _pmdabpftrace_install
# Installed by PCP QA test $seq on `date`
[dynamic_scripts]
enabled = true
auth_enabled = false
[bpftrace]
# ridiculously small for test5 running on (potentially) slow VMs
max_throughput = 4096
EOF
echo "=== bpftrace script without variables ==="
./src/store_and_fetch bpftrace.control.register "// name: test1
tracepoint:raw_syscalls:sys_enter { }" | grep -o '"error": "no bpftrace variables or printf statements found, please include at least one variable or printf statement in your script"'
echo
echo "=== invalid probe ==="
pmstore bpftrace.control.register "// name: test2
does_not_exist { @c = count(); }"
_pmdabpftrace_wait_for_value bpftrace.scripts.test2.status '"error"'
# error message changed between bpftrace versions
pminfo -f bpftrace.scripts.test2.error >>$seq_full
pminfo -f bpftrace.scripts.test2.error \
| grep -E -q "(Invalid provider: 'does_not_exist')|(Unrecognized probe type: does_not_exist)|(Invalid probe type made it to attachpoint parser)|(Invalid probe type: does_not_exist)" \
&& echo "error message (invalid probe) found"
pminfo -f bpftrace.scripts.test2.exit_code | _filter_exit_code
echo
echo "=== syntax error ==="
pmstore bpftrace.control.register "// name: test3
tracepoint:raw_syscalls:sys_enter { @c = count(; }"
# 10sec (default) is not long enough on vm03
#
_pmdabpftrace_wait_for_value bpftrace.scripts.test3.status '"error"' 15
pminfo -f bpftrace.scripts.test3.error
pminfo -f bpftrace.scripts.test3.exit_code
echo
echo "=== too many attached tracepoints ==="
# kprobe:d* matches between 4000 and 6000 tracepoints, so more than enough
# ... pick the first 513 of 'em
#
# Note: we used to use kprobe:* here, but even though this matches
# a bazillion tracepoints, on some systems it counted as only
# 1 probe, so we never saw the 512 max exceeded; so now we're
# enumerating 513 explicit kprobes.
# Note: on vm20 (Ubuntu 20.04) this sort of tracepoint
# kprobe:dyn_constraint.isra.0
# causes bpftrace to choke at the .0 (not expecting an integer!)
# skip any tracepoints that match \.[0-9]
#
$sudo bpftrace -l "kprobe:d*" \
| sed -e '/\.[0-9]/d' \
| $PCP_AWK_PROG >$tmp.probe '
BEGIN { print "// name: test4" }
{ print $0 " { @c = count(); }" }
NR > 512 { exit }'
num_probes=`wc -l <$tmp.probe | sed -e 's/ *//g'`
num_probes=`expr $num_probes - 1`
if [ "$num_probes" -ne 513 ]
then
echo "Arrgh: expecting 513 probes, got $num_probes. See $seq.full"
echo "num_probes=$num_probes" >>$seq_full
cat $tmp.probe >>$seq_full
fi
pmstore bpftrace.control.register "`cat $tmp.probe`" 2>&1 \
| _filter_kprobe
_pmdabpftrace_wait_for_value bpftrace.scripts.test4.status '"error"' 15
# Note: Failure texts we've seen here include
# vm03 (Fedora 42)
# value "cannot attach kprobe, Invalid argument
# ERROR: Error attaching probe: kprobe:debug_registers_open"
# bozo (Ubuntu 24.04)
# value "ERROR: Can't attach to 514 probes because it exceeds the current limit of 512 probes.
# You can increase the limit through the BPFTRACE_MAX_PROBES environment variable, but BE CAREFUL since a high number of probes attached can cause your system to crash."
#
pminfo -f bpftrace.scripts.test4.error \
| tee -a $seq_full \
| sed \
-e 's/ [1-9][0-9]* / PROBES /g' \
-e 's/"ERROR: /"/' \
-e '/value "Can'"'"'t attach to PROBES probes/{
s/value ".*"*/value "<kprobes error babble>"/
n
/^You can increase the limit through/d
}' \
-e '/value "Error attaching probe: '"'"'kprobe:\*'"'"'"/{
s/value ".*"*/value "<kprobes error babble>"/
}' \
-e '/value "cannot attach kprobe, Invalid argument/{
s/value ".*"*/value "<kprobes error babble>"/
n
/^ERROR: Error attaching probe: kprobe:/d
}' \
-e '/value "create_probe_event: .* Too many open files/{
s/value ".*"*/value "<kprobes error babble>"/
n
/^ERROR: Error attaching probe: kprobe:/d
}' \
-e '/value "Unable to attach probe: kprobe:dbg_get_reg. /{
s/value ".*"/value "<kprobes error babble>"/
}'
# end
pminfo -f bpftrace.scripts.test4.exit_code \
| sed -e '/value/s/ 255$/ 1/'
echo
echo "=== too much output ==="
pmstore bpftrace.control.register '// name: test5
profile:hz:999 { printf("test"); }'
_pmdabpftrace_wait_for_value bpftrace.scripts.test5.status '"error"' 20
pminfo -f bpftrace.scripts.test5.error | sed -e 's/ [1-9][0-9]* / LIMIT /g'
echo
echo "=== duplicate script name ==="
pmstore bpftrace.control.register "// name: test6
tracepoint:raw_syscalls:sys_enter { @x = count() }"
./src/store_and_fetch bpftrace.control.register "// name: test6
tracepoint:raw_syscalls:sys_enter { @x = count() }" | grep -o '"error": "Script name .* is already in use by another script."'
echo
_pmdabpftrace_remove
status=0
exit
|