14eaf97e8SMichael Petlan#!/bin/sh
24f673368SJiri Olsa# probe libc's inet_pton & backtrace it with ping
34f673368SJiri Olsa
44f673368SJiri Olsa# Installs a probe on libc's inet_pton function, that will use uprobes,
54f673368SJiri Olsa# then use 'perf trace' on a ping to localhost asking for just one packet
64f673368SJiri Olsa# with the a backtrace 3 levels deep, check that it is what we expect.
74f673368SJiri Olsa# This needs no debuginfo package, all is done using the libc ELF symtab
84f673368SJiri Olsa# and the CFI info in the binaries.
94f673368SJiri Olsa
105875cf4cSArnaldo Carvalho de Melo# SPDX-License-Identifier: GPL-2.0
114f673368SJiri Olsa# Arnaldo Carvalho de Melo <acme@kernel.org>, 2017
124f673368SJiri Olsa
13ed46a999SSamir Mulani. "$(dirname "$0")/lib/probe.sh"
14ed46a999SSamir Mulani. "$(dirname "$0")/lib/probe_vfs_getname.sh"
154f673368SJiri Olsa
164f673368SJiri Olsalibc=$(grep -w libc /proc/self/maps | head -1 | sed -r 's/.*[[:space:]](\/.*)/\1/g')
17*bb6b369cSTiezhu Yangnm -Dg $libc 2>/dev/null | grep -F -q inet_pton || exit 254
184f673368SJiri Olsa
1960089e42SSandipan Dasevent_pattern='probe_libc:inet_pton(\_[[:digit:]]+)?'
2060089e42SSandipan Das
2160089e42SSandipan Dasadd_libc_inet_pton_event() {
2260089e42SSandipan Das
2360089e42SSandipan Das	event_name=$(perf probe -f -x $libc -a inet_pton 2>&1 | tail -n +2 | head -n -5 | \
2460089e42SSandipan Das			grep -P -o "$event_pattern(?=[[:space:]]\(on inet_pton in $libc\))")
2560089e42SSandipan Das
26ed46a999SSamir Mulani	if [ $? -ne 0 ] || [ -z "$event_name" ] ; then
2760089e42SSandipan Das		printf "FAIL: could not add event\n"
2860089e42SSandipan Das		return 1
2960089e42SSandipan Das	fi
3060089e42SSandipan Das}
3160089e42SSandipan Das
324f673368SJiri Olsatrace_libc_inet_pton_backtrace() {
3398c6c8a1SKim Phillips
3498c6c8a1SKim Phillips	expected=`mktemp -u /tmp/expected.XXX`
3598c6c8a1SKim Phillips
3660089e42SSandipan Das	echo "ping[][0-9 \.:]+$event_name: \([[:xdigit:]]+\)" > $expected
3798c6c8a1SKim Phillips	echo ".*inet_pton\+0x[[:xdigit:]]+[[:space:]]\($libc|inlined\)$" >> $expected
384f673368SJiri Olsa	case "$(uname -m)" in
394f673368SJiri Olsa	s390x)
40b31a8cc1SThomas Richter		eventattr='call-graph=dwarf,max-stack=4'
4198c6c8a1SKim Phillips		echo "(__GI_)?getaddrinfo\+0x[[:xdigit:]]+[[:space:]]\($libc|inlined\)$" >> $expected
4298c6c8a1SKim Phillips		echo "main\+0x[[:xdigit:]]+[[:space:]]\(.*/bin/ping.*\)$" >> $expected
434f673368SJiri Olsa		;;
443eae52f8SSandipan Das	ppc64|ppc64le)
453eae52f8SSandipan Das		eventattr='max-stack=4'
463eae52f8SSandipan Das		echo "gaih_inet.*\+0x[[:xdigit:]]+[[:space:]]\($libc\)$" >> $expected
473eae52f8SSandipan Das		echo "getaddrinfo\+0x[[:xdigit:]]+[[:space:]]\($libc\)$" >> $expected
48bff5a556SSeeteena Thoufeek		echo ".*(\+0x[[:xdigit:]]+|\[unknown\])[[:space:]]\(.*/bin/ping.*\)$" >> $expected
493eae52f8SSandipan Das		;;
504f673368SJiri Olsa	*)
514f673368SJiri Olsa		eventattr='max-stack=3'
5216329364SArnaldo Carvalho de Melo		echo ".*(\+0x[[:xdigit:]]+|\[unknown\])[[:space:]]\(.*/bin/ping.*\)$" >> $expected
534f673368SJiri Olsa		;;
544f673368SJiri Olsa	esac
554f673368SJiri Olsa
5698c6c8a1SKim Phillips	perf_data=`mktemp -u /tmp/perf.data.XXX`
5798c6c8a1SKim Phillips	perf_script=`mktemp -u /tmp/perf.script.XXX`
58766b0beeSAthira Rajeev
59766b0beeSAthira Rajeev	# Check presence of libtraceevent support to run perf record
60766b0beeSAthira Rajeev	skip_no_probe_record_support "$event_name/$eventattr/"
61766b0beeSAthira Rajeev	[ $? -eq 2 ] && return 2
62766b0beeSAthira Rajeev
6360089e42SSandipan Das	perf record -e $event_name/$eventattr/ -o $perf_data ping -6 -c 1 ::1 > /dev/null 2>&1
6484cce3d6SAthira Rajeev	# check if perf data file got created in above step.
6584cce3d6SAthira Rajeev	if [ ! -e $perf_data ]; then
6684cce3d6SAthira Rajeev		printf "FAIL: perf record failed to create \"%s\" \n" "$perf_data"
6784cce3d6SAthira Rajeev		return 1
6884cce3d6SAthira Rajeev	fi
69b963c1d6SArnaldo Carvalho de Melo	perf script -i $perf_data | tac | grep -m1 ^ping -B9 | tac > $perf_script
704f673368SJiri Olsa
7198c6c8a1SKim Phillips	exec 3<$perf_script
7298c6c8a1SKim Phillips	exec 4<$expected
7398c6c8a1SKim Phillips	while read line <&3 && read -r pattern <&4; do
7498c6c8a1SKim Phillips		[ -z "$pattern" ] && break
754f673368SJiri Olsa		echo $line
76818448e9STiezhu Yang		echo "$line" | grep -E -q "$pattern"
774f673368SJiri Olsa		if [ $? -ne 0 ] ; then
7898c6c8a1SKim Phillips			printf "FAIL: expected backtrace entry \"%s\" got \"%s\"\n" "$pattern" "$line"
7983e3b6d7SSandipan Das			return 1
804f673368SJiri Olsa		fi
814f673368SJiri Olsa	done
824f673368SJiri Olsa
8310f354a3SSandipan Das	# If any statements are executed from this point onwards,
8410f354a3SSandipan Das	# the exit code of the last among these will be reflected
8510f354a3SSandipan Das	# in err below. If the exit code is 0, the test will pass
8610f354a3SSandipan Das	# even if the perf script output does not match.
874f673368SJiri Olsa}
884f673368SJiri Olsa
8960089e42SSandipan Dasdelete_libc_inet_pton_event() {
9060089e42SSandipan Das
9160089e42SSandipan Das	if [ -n "$event_name" ] ; then
9260089e42SSandipan Das		perf probe -q -d $event_name
9360089e42SSandipan Das	fi
9460089e42SSandipan Das}
9560089e42SSandipan Das
964f673368SJiri Olsa# Check for IPv6 interface existence
97*bb6b369cSTiezhu Yangip a sh lo | grep -F -q inet6 || exit 2
984f673368SJiri Olsa
994f673368SJiri Olsaskip_if_no_perf_probe && \
10060089e42SSandipan Dasadd_libc_inet_pton_event && \
1014f673368SJiri Olsatrace_libc_inet_pton_backtrace
1024f673368SJiri Olsaerr=$?
10398c6c8a1SKim Phillipsrm -f ${perf_data} ${perf_script} ${expected}
10460089e42SSandipan Dasdelete_libc_inet_pton_event
1054f673368SJiri Olsaexit $err
106