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

eugene.loh at oracle.com eugene.loh at oracle.com
Tue Jun 3 04:21:46 UTC 2025


From: Eugene Loh <eugene.loh at oracle.com>

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>
---
 libdtrace/dt_prov_uprobe.c          |   2 +-
 test/unittest/usdt/tst.pidprobes.sh | 114 ++++++++++------------------
 2 files changed, 40 insertions(+), 76 deletions(-)

diff --git a/libdtrace/dt_prov_uprobe.c b/libdtrace/dt_prov_uprobe.c
index 26f513fe..aecb07d5 100644
--- a/libdtrace/dt_prov_uprobe.c
+++ b/libdtrace/dt_prov_uprobe.c
@@ -901,7 +901,7 @@ static dt_probe_t *create_underlying(dtrace_hdl_t *dtp,
 	pd.fun = "";
 	pd.prb = prb;
 
-fprintf(stderr, "Underlying probe %s:%s:%s:%s @ %lx\n", psp->pps_prv, psp->pps_mod, psp->pps_fn, psp->pps_prb, psp->pps_off);
+// fprintf(stderr, "Underlying probe %s:%s:%s:%s @ %lx\n", psp->pps_prv, psp->pps_mod, psp->pps_fn, psp->pps_prb, psp->pps_off);
 	dt_dprintf("Providing underlying probe %s:%s:%s:%s @ %lx\n", psp->pps_prv,
 		   psp->pps_mod, psp->pps_fn, psp->pps_prb, psp->pps_off);
 	uprp = dt_probe_lookup(dtp, &pd);
diff --git a/test/unittest/usdt/tst.pidprobes.sh b/test/unittest/usdt/tst.pidprobes.sh
index 0c75d796..6a1fa984 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.43.5




More information about the DTrace-devel mailing list