[DTrace-devel] [PATCH v2 5/6] test: Add USDT tests for deferred detection

Kris Van Hees kris.van.hees at oracle.com
Mon Oct 28 20:34:25 UTC 2024


On Wed, Oct 09, 2024 at 06:26:13PM -0400, eugene.loh at oracle.com wrote:
> From: Eugene Loh <eugene.loh at oracle.com>
> 
> When new USDT processes start up, we do not immediately trace
> them.  First, dtprobed has to see these processes and then dtrace
> has to find them.  Hence, many of our tests XFAIL.
> 
> Add some tests that check USDT tracing on processes that start
> after the dtrace session has started, allowing for the possibility
> that tracing does not start until after the trigger is already
> underway.
> 
> There are two cases to consider.  One is when there is a USDT
> process running when the dtrace session starts.  In this case,
> an underlying probe is attached and later USDT processes just
> get added on.  Another case is when no USDT processes are running
> when the dtrace session starts.  In this case, -Z must be specified,
> and the underlying probe will not be attached until one of the USDT
> processes is detected.
> 
> 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.defer-Z.r  |   1 +
>  test/unittest/usdt/tst.defer-Z.sh | 153 ++++++++++++++++++++++++++++
>  test/unittest/usdt/tst.defer.r    |   1 +
>  test/unittest/usdt/tst.defer.sh   | 160 ++++++++++++++++++++++++++++++
>  4 files changed, 315 insertions(+)
>  create mode 100644 test/unittest/usdt/tst.defer-Z.r
>  create mode 100755 test/unittest/usdt/tst.defer-Z.sh
>  create mode 100644 test/unittest/usdt/tst.defer.r
>  create mode 100755 test/unittest/usdt/tst.defer.sh
> 
> diff --git a/test/unittest/usdt/tst.defer-Z.r b/test/unittest/usdt/tst.defer-Z.r
> new file mode 100644
> index 000000000..2e9ba477f
> --- /dev/null
> +++ b/test/unittest/usdt/tst.defer-Z.r
> @@ -0,0 +1 @@
> +success
> diff --git a/test/unittest/usdt/tst.defer-Z.sh b/test/unittest/usdt/tst.defer-Z.sh
> new file mode 100755
> index 000000000..52e92eb6b
> --- /dev/null
> +++ b/test/unittest/usdt/tst.defer-Z.sh
> @@ -0,0 +1,153 @@
> +#!/bin/bash
> +#
> +# Oracle Linux DTrace.
> +# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
> +# Licensed under the Universal Permissive License v 1.0 as shown at
> +# http://oss.oracle.com/licenses/upl.
> +#
> +# This test verifies that USDT will see new processes, even if detection
> +# is deferred -- that is, DTrace does not know about a new USDT process
> +# until after it's started running.
> +#
> +# In this test, all processes are started after the DTrace session has started.
> +# So the USDT probes will not be recognized at first and -Z must be used.
> +
> +dtrace=$1
> +trigger=`pwd`/test/triggers/usdt-tst-defer
> +
> +# Set up test directory.
> +
> +DIRNAME=$tmpdir/defer-Z.$$.$RANDOM
> +mkdir -p $DIRNAME
> +cd $DIRNAME
> +
> +# Make a private copy of the trigger executable so that we get our
> +# own DOF stash.
> +
> +cp $trigger main
> +
> +# Start dtrace.
> +
> +$dtrace $dt_flags -Zwq -o dtrace.out -n '
> +testprov*:::foo
> +{
> +	raise(SIGUSR1);
> +}
> +testprov*0:::bar,
> +testprov*1:::bar,
> +testprov*2:::bar,
> +testprov*3:::bar,
> +testprov*4:::bar
> +{
> +	@[pid, 0] = sum(arg0);
> +	@[pid, 1] = sum(arg1);
> +	@[pid, 2] = sum(arg2);
> +	@[pid, 3] = sum(pid % 100);
> +}' &
> +dtpid=$!
> +sleep 2
> +if [[ ! -d /proc/$dtpid ]]; then
> +	echo ERROR dtrace died
> +	exit 1
> +fi
> +
> +# Start processes concurrently.
> +
> +num=10
> +i=0
> +while [ $i -lt $num ]; do
> +	./main > main.out$i &
> +	pids[$i]=$!
> +	i=$(($i + 1))
> +done
> +
> +# Confirm that dtrace is still running (otherwise triggers run forever).
> +sleep 2
> +if [[ ! -d /proc/$dtpid ]]; then
> +	echo ERROR dtrace died after triggers started
> +	i=0
> +	while [ $i -lt $num ]; do
> +		kill -USR1 ${pids[$i]}
> +		wait       ${pids[$i]}
> +		i=$(($i + 1))
> +	done
> +	exit 1
> +fi
> +
> +# Wait for processes to complete.
> +
> +i=0
> +while [ $i -lt $num ]; do
> +	wait ${pids[$i]}
> +	i=$(($i + 1))
> +done
> +
> +# Kill the dtrace process.
> +
> +kill $dtpid
> +wait
> +
> +# Check the program output (main.out$i files).
> +
> +i=0
> +while [ $i -lt $num ]; do
> +	if [ $((${pids[$i]} % 10)) -lt 5 ]; then
> +		nphase2bar=10
> +	else
> +		nphase2bar=0
> +	fi
> +	echo "${pids[$i]}: undefined 0 0 10 10 $nphase2bar" > main.out$i.expected
> +	awk '
> +	    $3 == "1" { $3 =   0 }   # in phase 1, round 1 down to 0
> +	    $4 == "1" { $4 =   0 }   # in phase 1, round 1 down to 0
> +	    { $2 = "undefined"; print }' main.out$i > main.out$i.post
> +	if ! diff -q main.out$i.post main.out$i.expected; then
> +		echo program output looks wrong for DTrace case $i
> +		echo === was ===
> +		cat main.out$i
> +		echo === got ===
> +		cat main.out$i.post
> +		echo === expected ===
> +		cat main.out$i.expected
> +		exit 1
> +	fi
> +	i=$(($i + 1))
> +done
> +
> +# Check the dtrace output.
> +
> +#     regularize the dtrace output
> +awk 'NF != 0 { print $1, $2, $3 }' dtrace.out | sort > dtrace.out.post
> +
> +#     determine what to expect
> +
> +i=0
> +while [ $i -lt $num ]; do
> +	if [ $((${pids[$i]} % 10)) -lt 5 ]; then
> +		x=$(((${pids[$i]} % 100) * 10))
> +		echo ${pids[$i]} 0 45 >> dtrace.out.expected
> +		echo ${pids[$i]} 1 65 >> dtrace.out.expected
> +		echo ${pids[$i]} 2 90 >> dtrace.out.expected
> +		echo ${pids[$i]} 3 $x >> dtrace.out.expected
> +	fi
> +
> +	i=$(($i + 1))
> +done
> +
> +#     diff
> +if ! sort dtrace.out.expected | diff -q - dtrace.out.post; then
> +	echo dtrace output looks wrong for DTrace case $i
> +	echo === was ===
> +	cat dtrace.out
> +	echo === got ===
> +	cat dtrace.out.post
> +	echo === expected ===
> +	sort dtrace.out.expected
> +	echo === diff ===
> +	sort dtrace.out.expected | diff - dtrace.out.post
> +	exit 1
> +fi
> +
> +echo success
> +
> +exit 0
> diff --git a/test/unittest/usdt/tst.defer.r b/test/unittest/usdt/tst.defer.r
> new file mode 100644
> index 000000000..2e9ba477f
> --- /dev/null
> +++ b/test/unittest/usdt/tst.defer.r
> @@ -0,0 +1 @@
> +success
> diff --git a/test/unittest/usdt/tst.defer.sh b/test/unittest/usdt/tst.defer.sh
> new file mode 100755
> index 000000000..02ed1a767
> --- /dev/null
> +++ b/test/unittest/usdt/tst.defer.sh
> @@ -0,0 +1,160 @@
> +#!/bin/bash
> +#
> +# Oracle Linux DTrace.
> +# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
> +# Licensed under the Universal Permissive License v 1.0 as shown at
> +# http://oss.oracle.com/licenses/upl.
> +#
> +# This test verifies that USDT will see new processes, even if detection
> +# is deferred -- that is, DTrace does not know about a new USDT process
> +# until after it's started running.
> +#
> +# In this test, a process is started before the DTrace session has started.
> +# So the USDT probes will be recognized at first and -Z need not be used.
> +
> +dtrace=$1
> +trigger=`pwd`/test/triggers/usdt-tst-defer
> +
> +# Set up test directory.
> +
> +DIRNAME=$tmpdir/defer.$$.$RANDOM
> +mkdir -p $DIRNAME
> +cd $DIRNAME
> +
> +# Make a private copy of the trigger executable so that we get our
> +# own DOF stash.
> +
> +cp $trigger main
> +
> +# Start one process.
> +
> +./main > main.out0 &
> +pids[0]=$!
> +i=1
> +
> +# Figure out the pid's trailing digit.
> +
> +lastdigit=$((${pids[0]} % 10))
> +
> +# Start dtrace.
> +
> +$dtrace $dt_flags -wq -o dtrace.out -n '
> +testprov*:::foo
> +{
> +	raise(SIGUSR1);
> +}
> +testprov*'$lastdigit':::bar
> +{
> +	@[pid, 0] = sum(arg0);
> +	@[pid, 1] = sum(arg1);
> +	@[pid, 2] = sum(arg2);
> +	@[pid, 3] = sum(pid % 100);
> +}' &
> +dtpid=$!
> +sleep 2
> +if [[ ! -d /proc/$dtpid ]]; then
> +	echo ERROR dtrace died
> +	kill -USR1 ${pids[0]}
> +	wait       ${pids[0]}
> +	exit 1
> +fi
> +
> +# Start remaining processes.
> +
> +num=10
> +while [ $i -lt $num ]; do
> +	./main > main.out$i &
> +	pids[$i]=$!
> +	i=$(($i + 1))
> +done
> +
> +# Confirm that dtrace is still running (otherwise triggers run forever).
> +sleep 2
> +if [[ ! -d /proc/$dtpid ]]; then
> +	echo ERROR dtrace died after triggers started
> +	i=0
> +	while [ $i -lt $num ]; do
> +		kill -USR1 ${pids[$i]}
> +		wait       ${pids[$i]}
> +		i=$(($i + 1))
> +	done
> +	exit 1
> +fi
> +
> +# Wait for processes to complete.
> +
> +i=0
> +while [ $i -lt $num ]; do
> +	wait ${pids[$i]}
> +	i=$(($i + 1))
> +done
> +
> +# Kill the dtrace process.
> +
> +kill $dtpid
> +wait
> +
> +# Check the program output (main.out$i files).
> +
> +i=0
> +while [ $i -lt $num ]; do
> +	if [ $((${pids[$i]} % 10)) -eq $lastdigit ]; then
> +		nphase2bar=10
> +	else
> +		nphase2bar=0
> +	fi
> +	echo "${pids[$i]}: undefined 0 0 10 10 $nphase2bar" > main.out$i.expected
> +	awk '
> +	    $3 == "1" { $3 =   0 }   # in phase 1, round 1 down to 0
> +	    $4 == "1" { $4 =   0 }   # in phase 1, round 1 down to 0
> +	    { $2 = "undefined"; print }' main.out$i > main.out$i.post
> +	if ! diff -q main.out$i.post main.out$i.expected; then
> +		echo program output looks wrong for DTrace case $i
> +		echo === was ===
> +		cat main.out$i
> +		echo === got ===
> +		cat main.out$i.post
> +		echo === expected ===
> +		cat main.out$i.expected
> +		exit 1
> +	fi
> +	i=$(($i + 1))
> +done
> +
> +# Check the dtrace output.
> +
> +#     regularize the dtrace output
> +awk 'NF != 0 { print $1, $2, $3 }' dtrace.out | sort > dtrace.out.post
> +
> +#     determine what to expect
> +
> +i=0
> +while [ $i -lt $num ]; do
> +	if [ $((${pids[$i]} % 10)) -eq $lastdigit ]; then
> +		x=$(((${pids[$i]} % 100) * 10))
> +		echo ${pids[$i]} 0 45 >> dtrace.out.expected
> +		echo ${pids[$i]} 1 65 >> dtrace.out.expected
> +		echo ${pids[$i]} 2 90 >> dtrace.out.expected
> +		echo ${pids[$i]} 3 $x >> dtrace.out.expected
> +	fi
> +
> +	i=$(($i + 1))
> +done
> +
> +#     diff
> +if ! sort dtrace.out.expected | diff -q - dtrace.out.post; then
> +	echo dtrace output looks wrong for DTrace case $i
> +	echo === was ===
> +	cat dtrace.out
> +	echo === got ===
> +	cat dtrace.out.post
> +	echo === expected ===
> +	sort dtrace.out.expected
> +	echo === diff ===
> +	sort dtrace.out.expected | diff - dtrace.out.post
> +	exit 1
> +fi
> +
> +echo success
> +
> +exit 0
> -- 
> 2.43.5
> 



More information about the DTrace-devel mailing list