[DTrace-devel] [PATCH REVIEW] work: run under valgrind

Kris Van Hees kris.van.hees at oracle.com
Fri Oct 8 11:56:02 PDT 2021


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

... and I added it to my local dev branch so I will push it later today.

On Thu, Sep 09, 2021 at 12:14:04PM +0100, Nick Alcock wrote:
> Running BEGIN/END probes under valgrind failed because these probes work
> by dropping uprobes on DTrace itself, and uprobes fail if the uprobed
> process is being valgrinded: the breakpoint instruction inserted by
> uprobes is translated into VEX IR and then emulated by valgrind, and the
> emulation is located at a different address than the address originally
> used by the kernel: so the kernel has no idea it was a uprobe, and
> passes the breakpoint through to dtrace itself, killing it with a
> SIGTRAP.
> 
> The solution is to use the bizarrely-named VALGRIND_NON_SIMD_CALL0
> request to call the probes when valgrind is in use.  This asks valgrind
> to invoke a function on the real CPU rather than the emulated one, which
> invokes it from the right address, so the kernel spots the uprobe for
> what it is. VALGRIND_NON_SIMD_CALL* has harsh and barely-documented
> requirements on what it can be used to call, but our probe functions are
> entirely empty, so we can be pretty sure it'll always work for us.
> 
> Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
> Orabug: 32760574
> ---
>  dtrace.spec         |  2 +-
>  libdtrace/dt_work.c | 11 +++++++++--
>  2 files changed, 10 insertions(+), 3 deletions(-)
> 
> diff --git a/dtrace.spec b/dtrace.spec
> index 9098570f849d..a4c0e097f7ee 100644
> --- a/dtrace.spec
> +++ b/dtrace.spec
> @@ -46,7 +46,7 @@ License:      Universal Permissive License (UPL), Version 1.0
>  Group:        Development/Tools
>  Requires:     cpp elfutils-libelf zlib libpcap
>  BuildRequires: glibc-headers bison flex zlib-devel elfutils-libelf-devel
> -BuildRequires: glibc-static %{glibc32} wireshark libpcap-devel
> +BuildRequires: glibc-static %{glibc32} wireshark libpcap-devel valgrind-devel
>  BuildRequires: kernel%{variant}-devel = %{build_kernel}
>  BuildRequires: gcc-bpf-unknown-none
>  BuildRequires: binutils-bpf-unknown-none
> diff --git a/libdtrace/dt_work.c b/libdtrace/dt_work.c
> index 108eef9ac6f4..ff2a2458ad57 100644
> --- a/libdtrace/dt_work.c
> +++ b/libdtrace/dt_work.c
> @@ -18,6 +18,7 @@
>  #include <port.h>
>  #include <linux/perf_event.h>
>  #include <sys/epoll.h>
> +#include <valgrind/valgrind.h>
>  
>  void
>  BEGIN_probe(void)
> @@ -109,7 +110,10 @@ dtrace_go(dtrace_hdl_t *dtp, uint_t cflags)
>  	if (err)
>  		return err;
>  
> -	BEGIN_probe();
> +	if (RUNNING_ON_VALGRIND)
> +		VALGRIND_NON_SIMD_CALL0(BEGIN_probe);
> +	else
> +		BEGIN_probe();
>  
>  	dtp->dt_active = 1;
>  	dtp->dt_beganon = dt_state_get_beganon(dtp);
> @@ -141,7 +145,10 @@ dtrace_stop(dtrace_hdl_t *dtp)
>  	if (dt_state_get_activity(dtp) < DT_ACTIVITY_DRAINING)
>  		dt_state_set_activity(dtp, DT_ACTIVITY_DRAINING);
>  
> -	END_probe();
> +	if (RUNNING_ON_VALGRIND)
> +		VALGRIND_NON_SIMD_CALL0(END_probe);
> +	else
> +		END_probe();
>  
>  	dtp->dt_stopped = 1;
>  	dtp->dt_endedon = dt_state_get_endedon(dtp);
> -- 
> 2.33.0.256.gb827f06fa9
> 
> 
> _______________________________________________
> DTrace-devel mailing list
> DTrace-devel at oss.oracle.com
> https://oss.oracle.com/mailman/listinfo/dtrace-devel



More information about the DTrace-devel mailing list