Linux DTrace development list
 help / color / mirror / Atom feed
* [PATCH] test:  Adapt USDT PC search for USDT LTO changes
@ 2025-06-03  4:21 eugene.loh
  2025-06-07  5:52 ` Kris Van Hees
  0 siblings, 1 reply; 2+ messages in thread
From: eugene.loh @ 2025-06-03  4:21 UTC (permalink / raw)
  To: dtrace, dtrace-devel

From: Eugene Loh <eugene.loh@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@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


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] test:  Adapt USDT PC search for USDT LTO changes
  2025-06-03  4:21 [PATCH] test: Adapt USDT PC search for USDT LTO changes eugene.loh
@ 2025-06-07  5:52 ` Kris Van Hees
  0 siblings, 0 replies; 2+ messages in thread
From: Kris Van Hees @ 2025-06-07  5:52 UTC (permalink / raw)
  To: eugene.loh; +Cc: dtrace, dtrace-devel

Reviewed-by: Kris Van Hees <kris.van.hees@oracle.com>

On Tue, Jun 03, 2025 at 12:21:46AM -0400, eugene.loh@oracle.com wrote:
> From: Eugene Loh <eugene.loh@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@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
> 

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-06-07  5:52 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-03  4:21 [PATCH] test: Adapt USDT PC search for USDT LTO changes eugene.loh
2025-06-07  5:52 ` Kris Van Hees

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox