[DTrace-devel] [PATCH 1/2] Add support for copyout() subroutine
Eugene Loh
eugene.loh at oracle.com
Sat Jan 14 06:01:21 UTC 2023
The cg part of the patch looks good, other than that the
dt_regset_free_args() should be moved to right after the function call.
I note that below.
This patch needs a positive test that checks correct operation of the
new feature. Here is a possibility:
#!/bin/bash
#
# Oracle Linux DTrace.
# Copyright (c) 2023, 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.
dtrace=$1
DIRNAME="$tmpdir/copyout.$$.$RANDOM"
mkdir -p $DIRNAME
cd $DIRNAME
cat << EOF > main.c
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main(int c, char **v) {
int fd = open("/dev/null", O_WRONLY);
char s[256];
sprintf(s, "hello world");
write(fd, s, strlen(s));
printf("%s\n", s);
return 0;
}
EOF
gcc main.c
if [ $? -ne 0 ]; then
echo "compilation error"
exit 1
fi
$dtrace $dt_flags -qwn '
syscall::write:entry
/pid == $target/
{
copyout(strjoin("HELLO ", "WORLD"), arg1, 256);
exit(0);
}' -c ./a.out
if [ $? -ne 0 ]; then
echo "DTrace error"
cat $tmpfile
exit 1
fi
exit 0
And then the .r file should have HELLO WORLD.
And then perhaps the copyout tests should probably be in their own func/
subdirectory, as is done for copyin.
Why is copyoutstr() not part of this patch? Is it just the extra work
of figuring out the string length?
The test test/unittest/funcs/err.copyoutstrbadaddr.sh uses copyout().
It should use copyoutstr(). (Yes, that problem predates this patch.)
This patch should remove the XFAIL on test/unittest/dif/copyout.d.
On 1/13/23 14:43, Kris Van Hees via DTrace-devel wrote:
> diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> +static void
> +dt_cg_subr_copyout(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> +{
> + dt_node_t *src = dnp->dn_args;
> + dt_node_t *dst = src->dn_list;
> + dt_node_t *size = dst->dn_list;
> + uint_t lbl_ok = dt_irlist_label(dlp);
> +
> + dt_cg_clsflags(yypcb, DTRACEACT_PROC_DESTRUCTIVE, dnp);
> +
> + TRACE_REGSET(" subr-copyout:Begin");
> +
> + /* Validate the source pointer. */
> + dt_cg_node(src, dlp, drp);
> + dt_cg_check_ptr_arg(dlp, drp, src);
> +
> + /* Validate the destination pointer. */
> + dt_cg_node(dst, dlp, drp);
> + dt_cg_check_notnull(dlp, drp, dst->dn_reg);
> +
> + /* Size for the copy operation. */
> + dt_cg_node(size, dlp, drp);
> +
> + if (dt_regset_xalloc_args(drp) == -1)
> + longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> +
> + emit(dlp, BPF_MOV_REG(BPF_REG_1, dst->dn_reg));
> + emit(dlp, BPF_MOV_REG(BPF_REG_2, src->dn_reg));
> + emit(dlp, BPF_MOV_REG(BPF_REG_3, size->dn_reg));
> + dt_regset_xalloc(drp, BPF_REG_0);
> + emit(dlp, BPF_CALL_HELPER(BPF_FUNC_probe_write_user));
> +
> + /*
> + * At this point the src is validated, so any problem must be with
> + * the dst address.
> + */
> + emit(dlp, BPF_BRANCH_IMM(BPF_JEQ, BPF_REG_0, 0, lbl_ok));
> + dt_regset_free(drp, BPF_REG_0);
> + dt_regset_free_args(drp);
The dt_regset_free_args() should be moved to right after the
BPF_CALL_HELPER().
> + dt_cg_probe_error(yypcb, DTRACEFLT_BADADDR, DT_ISREG, dst->dn_reg);
> + emitl(dlp, lbl_ok,
> + BPF_NOP());
> +
> + dt_regset_free(drp, src->dn_reg);
> + dt_regset_free(drp, dst->dn_reg);
> + dt_regset_free(drp, size->dn_reg);
> +
> + TRACE_REGSET(" subr-copyout:End ");
> +}
More information about the DTrace-devel
mailing list