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

Ryan Stone rysto32 at gmail.com
Sat Nov 5 20:30:50 UTC 2011


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
@@ -220,8 +220,12 @@ 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
@@ -38,6 +38,7 @@ 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 "^$"`
@@ -46,9 +47,9 @@ 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
@@ -96,6 +97,7 @@ s/\$//g
                sysmk = \"$sysmk\"
                systrace = \"$systrace\"
                systracetmp = \"$systracetmp\"
+               systraceret = \"$systraceret\"
                compat = \"$compat\"
                compat4 = \"$compat4\"
                compat6 = \"$compat6\"
@@ -179,9 +181,12 @@ 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 ~ /^;/ {
@@ -202,6 +207,7 @@ s/\$//g
                print > sysnames
                print > systrace
                print > systracetmp
+               print > systraceret
                savesyscall = syscall
                next
        }
@@ -216,6 +222,7 @@ s/\$//g
                print > sysnames
                print > systrace
                print > systracetmp
+               print > systraceret
                syscall = savesyscall
                next
        }
@@ -230,6 +237,7 @@ s/\$//g
                print > sysnames
                print > systrace
                print > systracetmp
+               print > systraceret
                next
        }
        syscall != $1 {
@@ -303,7 +311,8 @@ s/\$//g
                        parserr($end, ")")
                end--

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

                funcname=$f

@@ -387,6 +396,7 @@ 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
@@ -406,6 +416,10 @@ 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
@@ -623,6 +637,7 @@ 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
@@ -633,4 +648,5 @@ 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


More information about the freebsd-current mailing list