[PATCH] Fix types of arguments to dtrace syscall return probes

From: Ryan Stone <rysto32_at_gmail.com>
Date: Sat, 5 Nov 2011 16:30:48 -0400
Currently if you try to use the args[] array passed to a syscall
return probe, you get variables with the wrong type.  This is because
the systrace implementation is currently using the same function to
provide the same argument types for both the entry and return probes,
which is completely wrong.  For example:

# dtrace -v -l -n syscall::mmap:return
   ID   PROVIDER            MODULE                          FUNCTION NAME
32159    syscall                                                mmap return

        Probe Description Attributes
                Identifier Names: Private
                Data Semantics:   Private
                Dependency Class: ISA

        Argument Attributes
                Identifier Names: Private
                Data Semantics:   Private
                Dependency Class: ISA

        Argument Types
                args[0]: caddr_t
                args[1]: size_t
                args[2]: int
                args[3]: int
                args[4]: int
                args[5]: off_t

The following patch[1] fixes this and provides the correct type to all
return probes.  For example,

# dtrace -l -v -n syscall::mmap:return
   ID   PROVIDER            MODULE                          FUNCTION NAME
 2000    syscall           freebsd                              mmap return

        Probe Description Attributes
                Identifier Names: Private
                Data Semantics:   Private
                Dependency Class: Unknown

        Argument Attributes
                Identifier Names: Private
                Data Semantics:   Private
                Dependency Class: ISA

        Argument Types
                args[0]: caddr_t
                args[1]: caddr_t


The patch:
diff --git a/sys/cddl/dev/systrace/systrace.c b/sys/cddl/dev/systrace/systrace.c
index cc48747..31c11c2 100644
--- a/sys/cddl/dev/systrace/systrace.c
+++ b/sys/cddl/dev/systrace/systrace.c
_at__at_ -220,8 +220,12 _at__at_ systrace_getargdesc(void *arg, dtrace_id_t id,
void *parg, dtrace_argdesc_t *des
 {
        int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);

-       systrace_setargdesc(sysnum, desc->dtargd_ndx, desc->dtargd_native,
-           sizeof(desc->dtargd_native));
+       if (SYSTRACE_ISENTRY((uintptr_t)parg))
+               systrace_entry_setargdesc(sysnum, desc->dtargd_ndx,
+                   desc->dtargd_native, sizeof(desc->dtargd_native));
+       else
+               systrace_return_setargdesc(sysnum, desc->dtargd_ndx,
+                   desc->dtargd_native, sizeof(desc->dtargd_native));

        if (desc->dtargd_native[0] == '\0')
                desc->dtargd_ndx = DTRACE_ARGNONE;
diff --git a/sys/kern/makesyscalls.sh b/sys/kern/makesyscalls.sh
index d1162b5..1f081ce 100644
--- a/sys/kern/makesyscalls.sh
+++ b/sys/kern/makesyscalls.sh
_at__at_ -38,6 +38,7 _at__at_ sysinc="sysinc.switch.$$"
 sysarg="sysarg.switch.$$"
 sysprotoend="sysprotoend.$$"
 systracetmp="systrace.$$"
+systraceret="systraceret.$$"

 if [ -r capabilities.conf ]; then
        capenabled=`cat capabilities.conf | grep -v "^#" | grep -v "^$"`
_at__at_ -46,9 +47,9 _at__at_ else
        capenabled=""
 fi

-trap "rm $sysaue $sysdcl $syscompat $syscompatdcl $syscompat4
$syscompat4dcl $syscompat6 $syscompat6dcl $syscompat7 $syscompat7dcl
$sysent $sysinc $sysarg $sysprotoend $systracetmp" 0
+trap "rm $sysaue $sysdcl $syscompat $syscompatdcl $syscompat4
$syscompat4dcl $syscompat6 $syscompat6dcl $syscompat7 $syscompat7dcl
$sysent $sysinc $sysarg $sysprotoend $systracetmp $systraceret" 0

-touch $sysaue $sysdcl $syscompat $syscompatdcl $syscompat4
$syscompat4dcl $syscompat6 $syscompat6dcl $syscompat7 $syscompat7dcl
$sysent $sysinc $sysarg $sysprotoend $systracetmp
+touch $sysaue $sysdcl $syscompat $syscompatdcl $syscompat4
$syscompat4dcl $syscompat6 $syscompat6dcl $syscompat7 $syscompat7dcl
$sysent $sysinc $sysarg $sysprotoend $systracetmp $systraceret

 case $# in
     0) echo "usage: $0 input-file <config-file>" 1>&2
_at__at_ -96,6 +97,7 _at__at_ s/\$//g
                sysmk = \"$sysmk\"
                systrace = \"$systrace\"
                systracetmp = \"$systracetmp\"
+               systraceret = \"$systraceret\"
                compat = \"$compat\"
                compat4 = \"$compat4\"
                compat6 = \"$compat6\"
_at__at_ -179,9 +181,12 _at__at_ s/\$//g
                printf "\tint64_t *iarg  = (int64_t *) uarg;\n" > systrace
                printf "\tswitch (sysnum) {\n" > systrace

-               printf "static void\nsystrace_setargdesc(int sysnum,
int ndx, char *desc, size_t descsz)\n{\n\tconst char *p = NULL;\n" >
systracetmp
+               printf "static void\nsystrace_entry_setargdesc(int
sysnum, int ndx, char *desc, size_t descsz)\n{\n\tconst char *p =
NULL;\n" > systracetmp
                printf "\tswitch (sysnum) {\n" > systracetmp

+               printf "static void\nsystrace_return_setargdesc(int
sysnum, int ndx, char *desc, size_t descsz)\n{\n\tconst char *p =
NULL;\n" > systraceret
+               printf "\tswitch (sysnum) {\n" > systraceret
+
                next
        }
        NF == 0 || $1 ~ /^;/ {
_at__at_ -202,6 +207,7 _at__at_ s/\$//g
                print > sysnames
                print > systrace
                print > systracetmp
+               print > systraceret
                savesyscall = syscall
                next
        }
_at__at_ -216,6 +222,7 _at__at_ s/\$//g
                print > sysnames
                print > systrace
                print > systracetmp
+               print > systraceret
                syscall = savesyscall
                next
        }
_at__at_ -230,6 +237,7 _at__at_ s/\$//g
                print > sysnames
                print > systrace
                print > systracetmp
+               print > systraceret
                next
        }
        syscall != $1 {
_at__at_ -303,7 +311,8 _at__at_ s/\$//g
                        parserr($end, ")")
                end--

-               f++     #function return type
+               syscallret=$f
+               f++

                funcname=$f

_at__at_ -387,6 +396,7 _at__at_ s/\$//g
                parseline()
                printf("\t/* %s */\n\tcase %d: {\n", funcname,
syscall) > systrace
                printf("\t/* %s */\n\tcase %d:\n", funcname, syscall)
> systracetmp
+               printf("\t/* %s */\n\tcase %d:\n", funcname, syscall)
> systraceret
                if (argc > 0) {
                        printf("\t\tswitch(ndx) {\n") > systracetmp
                        printf("\t\tstruct %s *p = params;\n",
argalias) > systrace
_at__at_ -406,6 +416,10 _at__at_ s/\$//g
                                             argname[i], argtype[i]) > systrace
                        }
                        printf("\t\tdefault:\n\t\t\tbreak;\n\t\t};\n")
> systracetmp
+
+                       printf("\t\tif (ndx == 0 || ndx == 1)\n") > systraceret
+                       printf("\t\t\tp = \"%s\";\n", syscallret) > systraceret
+                       printf("\t\tbreak;\n") > systraceret
                }
                printf("\t\t*n_args = %d;\n\t\tbreak;\n\t}\n", argc) > systrace
                printf("\t\tbreak;\n") > systracetmp
_at__at_ -623,6 +637,7 _at__at_ s/\$//g
                    > syshdr
                printf "\tdefault:\n\t\t*n_args =
0;\n\t\tbreak;\n\t};\n}\n" > systrace
                printf "\tdefault:\n\t\tbreak;\n\t};\n\tif (p !=
NULL)\n\t\tstrlcpy(desc, p, descsz);\n}\n" > systracetmp
+               printf "\tdefault:\n\t\tbreak;\n\t};\n\tif (p !=
NULL)\n\t\tstrlcpy(desc, p, descsz);\n}\n" > systraceret
        } '

 cat $sysinc $sysent >> $syssw
_at__at_ -633,4 +648,5 _at__at_ cat $sysarg $sysdcl \
        $syscompat7 $syscompat7dcl \
        $sysaue $sysprotoend > $sysproto
 cat $systracetmp >> $systrace
+cat $systraceret >> $systrace


[1] Can also be found at
http://people.freebsd.org/~rstone/patches/dtrace_syscall_ret.diff
Received on Sat Nov 05 2011 - 19:30:50 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:20 UTC