[DTrace-devel] [PATCH 17/17] test: Adapt USDT PC search for USDT LTO changes

Kris Van Hees kris.van.hees at oracle.com
Sat Jun 7 06:15:07 UTC 2025


To check USDT PCs, we looked at disassembly for characteristics that
indicated USDT probes.

With LTO, however, USDT instrumentation has changed.

Therefore, use showUSDT in tst.pidprobes.sh to extract USDT PCs.

Note that tst.pidargs.sh and tst.pidargmap.sh depend on
tst.pidprobes.sh.  Therefore, those tests also benefit from this change.
They do not yet pass, however, since index 0 for args[] is said to be
out of range.

Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>
---
 test/unittest/usdt/tst.pidprobes.sh | 114 ++++++++++------------------
 1 file changed, 39 insertions(+), 75 deletions(-)

diff --git a/test/unittest/usdt/tst.pidprobes.sh b/test/unittest/usdt/tst.pidprobes.sh
index 72434eb9..24fbd518 100755
--- a/test/unittest/usdt/tst.pidprobes.sh
+++ b/test/unittest/usdt/tst.pidprobes.sh
@@ -19,6 +19,7 @@ mapping=${3:-}
 
 # Set up test directory.
 
+d=`pwd`
 DIRNAME=$tmpdir/pidprobes.$$.$RANDOM
 mkdir -p $DIRNAME
 cd $DIRNAME
@@ -74,9 +75,6 @@ if [ $? -ne 0 ]; then
 	echo "failed to compile test" >&2
 	exit 1
 fi
-if [[ `uname -m` = "aarch64" ]]; then
-	$OBJDUMP -d main.o > disasm_foo.txt.before
-fi
 $dtrace $dt_flags -G -64 -s prov.d main.o
 if [ $? -ne 0 ]; then
 	echo "failed to create DOF" >&2
@@ -183,84 +181,50 @@ if [ `awk 'NF != 0 { print $1 }' dtrace.out | uniq | wc -l` -ne 1 ]; then
 fi
 pid=`awk 'NF != 0 { print $1 }' dtrace.out | uniq`
 
-# From the disassembly, get the PCs for USDT probes.
-# Check libdtrace/dt_link.c's arch-dependent dt_modtext() to see
-# what sequence of instructions signal a USDT probe.
-
-if [[ `uname -m` = "x86_64" ]]; then
-
-	# It is the first of five nop instructions in a row.
-	# So track pc[-6], pc[-5], pc[-4], pc[-3], pc[-2], pc[-1], pc[0]
-	# as well as whether they are nop.
-
-	usdt_pcs_all=`awk '
-	BEGIN {
-		pc6 = -1; is_nop6 = 0;
-		pc5 = -1; is_nop5 = 0;
-		pc4 = -1; is_nop4 = 0;
-		pc3 = -1; is_nop3 = 0;
-		pc2 = -1; is_nop2 = 0;
-		pc1 = -1; is_nop1 = 0;
+# From showUSDT output, get the PCs for USDT probes.  We look for output like:
+#     Note usdt, type N:
+#       Offset 0xoffset
+#       Function Offset 0xfoffset
+#       Probe pyramid::foo:entry
+$d/test/utils/showUSDT main | awk '
+/^ *Note usdt, type / {
+	getline;
+	if (!match($0, /^ *Offset *0x[0-9a-f]* *$/)) {
+		print "ERROR: expect Offset";
+		exit(1);
 	}
-	{
-		# pc0 is current instruction
-		pc0 = strtonum("0x"$1);
-
-		# decide whether it is a nop
-		is_nop0 = 0;
-		if (NF == 3 &&
-		    $2 == "90" &&
-		    $3 == "nop")
-			is_nop0 = 1;
-
-		# report if pc[-5] is a USDT instruction
-		if (is_nop6 == 0 &&
-		    is_nop5 == 1 &&
-		    is_nop4 == 1 &&
-		    is_nop3 == 1 &&
-		    is_nop2 == 1 &&
-		    is_nop1 == 1 &&
-		    is_nop0 == 0)
-			print pc5;
-
-		# prepare advance to next instruction
-		pc6 = pc5;  is_nop6 = is_nop5;
-		pc5 = pc4;  is_nop5 = is_nop4;
-		pc4 = pc3;  is_nop4 = is_nop3;
-		pc3 = pc2;  is_nop3 = is_nop2;
-		pc2 = pc1;  is_nop2 = is_nop1;
-		pc1 = pc0;  is_nop1 = is_nop0;
-	}' disasm_foo.txt`
-
-	# We expect 4 USDT probes (2 USDT and 2 is-enabled).
-	if [ `echo $usdt_pcs_all | awk '{print NF}'` -ne 4 ]; then
-		echo ERROR: expected 4 USDT probes but got $usdt_pcs_all
-		cat disasm_foo.txt
-		exit 1
-	fi
+	off = strtonum($2);
 
-	# Separate them into regular and is-enabled PCs.
-	# We assume they alternate.
-	usdt_pcs=`echo $usdt_pcs_all | awk '{ print $1, $3 }'`
-	usdt_pcs_isenabled=`echo $usdt_pcs_all | awk '{ print $2, $4 }'`
+	getline;
+	if (!match($0, /^ *Function Offset *0x[0-9a-f]* *$/)) {
+		print "ERROR: expect Function Offset";
+		exit(1);
+	}
 
-elif [[ `uname -m` = "aarch64" ]]; then
+	getline;
+	if (!match($0, /^ *Probe pyramid::foo:entry/)) {
+		print "ERROR: expect Probe pyramid::foo:entry";
+		exit(1);
+	}
 
-	# The initial compilation of foo() makes it obvious where the
-	# USDT probes are.  We just have to add the function offset in.
-	usdt_pcs=`awk '/<__dtrace_pyramid___entry>/ { print strtonum("0x"$1) + '$pc0' }' disasm_foo.txt.before`
-	usdt_pcs_isenabled=`awk '/<__dtraceenabled_pyramid___entry>/ { print strtonum("0x"$1) + '$pc0' }' disasm_foo.txt.before`
+	print off, $0;
+} ' > usdt_pcs.txt
+if [ $? -ne 0 ]; then
+	echo ERROR: showUSDT output to awk
+	$d/test/utils/showUSDT main
+	exit 1
+fi
+usdt_pcs=`awk '!/is-enabled/ { sub("0x", ""); print $1}' usdt_pcs.txt`
+usdt_pcs_isenabled=`awk '/is-enabled/ { sub("0x", ""); print $1}' usdt_pcs.txt`
 
-	# We expect 4 USDT probes (2 USDT and 2 is-enabled).
-	if [ `echo $usdt_pcs | awk '{print NF}'` -ne 2 -o \
-	     `echo $usdt_pcs_isenabled | awk '{print NF}'` -ne 2 ]; then
-		echo ERROR: expected 4 USDT probes but got $usdt_pcs and $usdt_pcs_isenabled
-		cat disasm_foo.txt.before
-		exit 1
-	fi
+# We expect 2 USDT probes plus 2 is-enabled.
 
-else
-	echo ERROR unrecognized machine hardware name
+if [ `echo $usdt_pcs           | awk '{print NF}'` -ne 2 ]; then
+	echo ERROR: expected 2 USDT regular probes but got $usdt_pcs
+	exit 1
+fi
+if [ `echo $usdt_pcs_isenabled | awk '{print NF}'` -ne 2 ]; then
+	echo ERROR: expected 2 USDT is-enabled probes but got $usdt_pcs_isenabled
 	exit 1
 fi
 
-- 
2.45.2




More information about the DTrace-devel mailing list