]> sourceware.org Git - systemtap.git/commitdiff
Fix PR16616 by handling a NULL servername in sunrpc probes.
authorDavid Smith <dsmith@redhat.com>
Tue, 25 Feb 2014 19:24:11 +0000 (13:24 -0600)
committerDavid Smith <dsmith@redhat.com>
Tue, 25 Feb 2014 19:24:11 +0000 (13:24 -0600)
* tapset/linux/rpc.stp (sunrpc.clnt.entry): Use __rpc_format_servername()
  to generate the 'servername' convenience variable.
  (__rpc_format_servername): New function.
* tapset/linux/conversions.stp (kernel_string): Fix odd formatting of NULL
  value in the error message.

tapset/linux/conversions.stp
tapset/linux/rpc.stp

index 3627f59329e2d1600f5f026f33983afc403f2668..2eb49ccb1624321eb0b07994b48cb6b5525f111d 100644 (file)
@@ -20,8 +20,12 @@ function kernel_string:string (addr:long) %{ /* pure */
   kderef_string (destination, STAP_ARG_addr, MAXSTRINGLEN);
   if (0) {
 deref_fault: /* branched to from deref_string() */
+    /* Why '%1p' below? On newer kernels, the snprintf() function pads
+     * out '(null)' to the same width as other pointers, which looks
+     * really odd in the following error message. Setting a format
+     * width of '1' fixes this. */
     snprintf (CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
-        "kernel string copy fault at 0x%p", (void *) (uintptr_t) STAP_ARG_addr);
+        "kernel string copy fault at %1p", (void *) (uintptr_t) STAP_ARG_addr);
     CONTEXT->last_error = CONTEXT->error_buffer;
   }
 %}
index 10c9d74917673b912f3e2e7f67510db6ce345d9f..03e4b7559627b5bd54ae4fa3a22560d899045301 100644 (file)
@@ -165,7 +165,8 @@ probe _sunrpc.clnt.create_client.rpc_new_client_inline =
                args = $args
 %)
                __args = $args
-               servername = kernel_string($args->servername)
+               servername = __rpc_format_servername($args->servername,
+                                                    $args->address)
                progname = kernel_string($args->program->name)
                prog = $args->prognumber
                vers = vers_from_prog($args->program, $args->version)
@@ -179,7 +180,9 @@ probe _sunrpc.clnt.create_client.rpc_new_client_inline =
                args = __rpc_create_args[tid()]
 %)
                __args = __rpc_create_args[tid()]
-               servername = kernel_string(@cast(__args, "rpc_create_args", "kernel:sunrpc")->servername)
+               servername = __rpc_format_servername(@cast(__args, "rpc_create_args", "kernel:sunrpc")->servername,
+                                                    @cast(__args, "rpc_create_args", "kernel:sunrpc")->address)
+
                progname = kernel_string(@cast(__args, "rpc_create_args", "kernel:sunrpc")->program->name)
                prog = @cast(__args, "rpc_create_args", "kernel:sunrpc")->prognumber
                vers = vers_from_prog(@cast(__args, "rpc_create_args", "kernel:sunrpc")->program, @cast(__args, "rpc_create_args", "kernel:sunrpc")->version)
@@ -197,7 +200,8 @@ probe _sunrpc.clnt.create_client.rpc_new_client =
 {
        if (@defined($args)) {
                # kernel > 2.6.18
-               servername = kernel_string($args->servername)
+               servername = __rpc_format_servername($args->servername,
+                                                    $args->address)
                progname = kernel_string($args->program->name)
                prog = $args->prognumber
                vers = vers_from_prog($args->program, $args->version)
@@ -205,7 +209,7 @@ probe _sunrpc.clnt.create_client.rpc_new_client =
        }
        else {
                # kernel <= 2.6.18
-               servername = kernel_string($servname)
+               servername = __rpc_format_servername($servname, &$xprt->addr)
                progname = kernel_string($program->name)
                prog = $program->number
                vers = vers_from_prog($program, $vers)
@@ -220,7 +224,7 @@ probe _sunrpc.clnt.create_client.rpc_create_client =
        kernel.function("rpc_create_client") !,
        module("sunrpc").function("rpc_create_client")
 {
-       servername = kernel_string($servname)
+       servername = __rpc_format_servername($servname, &$xprt->addr)
        if (@defined($info)) {
                progname = kernel_string($info->name)
                prog = $info->number
@@ -286,9 +290,14 @@ probe _sunrpc.clnt.create_client.return.rpc_create_client =
 probe sunrpc.clnt.clone_client = kernel.function("rpc_clone_client") !,
        module("sunrpc").function("rpc_clone_client")
 {
-       servername = kernel_string(@choose_defined($clnt->cl_server,
-                                  @cast(rcu_dereference($clnt->cl_xprt),
-                                        "struct rpc_xprt")->servername))
+       if (@defined($clnt->cl_server))
+               servername = __rpc_format_servername($clnt->cl_server,
+                                                    &$clnt->cl_xprt->addr)
+       else {
+               __xprt = rcu_dereference($clnt->cl_xprt)
+               servername = __rpc_format_servername(@cast(__xprt, "rpc_xprt")->servername,
+                                                    &@cast(__xprt, "rpc_xprt")->addr)
+       }
        progname = kernel_string(@choose_defined($clnt->cl_program->name,
                                                 $clnt->cl_protname))
        prog = prog_from_clnt($clnt)
@@ -335,9 +344,14 @@ probe sunrpc.clnt.clone_client.return =
 probe sunrpc.clnt.shutdown_client = kernel.function("rpc_shutdown_client") !,
        module("sunrpc").function("rpc_shutdown_client")
 {
-       servername = kernel_string(@choose_defined($clnt->cl_server,
-                                  @cast(rcu_dereference($clnt->cl_xprt),
-                                        "struct rpc_xprt")->servername))
+       if (@defined($clnt->cl_server))
+               servername = __rpc_format_servername($clnt->cl_server,
+                                                    &$clnt->cl_xprt->addr)
+       else {
+               __xprt = rcu_dereference($clnt->cl_xprt)
+               servername = __rpc_format_servername(@cast(__xprt, "rpc_xprt")->servername,
+                                                    &@cast(__xprt, "rpc_xprt")->addr)
+       }
        progname = kernel_string(@choose_defined($clnt->cl_program->name,
                                                 $clnt->cl_protname))
        prog = prog_from_clnt($clnt)
@@ -408,9 +422,14 @@ probe sunrpc.clnt.bind_new_program =
        kernel.function("rpc_bind_new_program") !,
        module("sunrpc").function("rpc_bind_new_program")
 {
-       servername = kernel_string(@choose_defined($old->cl_server,
-                                  @cast(rcu_dereference($old->cl_xprt),
-                                        "struct rpc_xprt")->servername))
+       if (@defined($old->cl_server))
+               servername = __rpc_format_servername($old->cl_server,
+                                                    &$old->cl_xprt->addr)
+       else {
+               __xprt = rcu_dereference($old->cl_xprt)
+               servername = __rpc_format_servername(@cast(__xprt, "rpc_xprt")->servername,
+                                                    &@cast(__xprt, "rpc_xprt")->addr)
+       }
        old_progname = kernel_string(@choose_defined($old->cl_program->name,
                                                     $old->cl_protname))
        old_prog = prog_from_clnt($old)
@@ -450,9 +469,14 @@ probe sunrpc.clnt.bind_new_program.return =
 probe sunrpc.clnt.call_sync = kernel.function("rpc_call_sync") !,
        module("sunrpc").function("rpc_call_sync")
 {
-       servername = kernel_string(@choose_defined($clnt->cl_server,
-                                  @cast(rcu_dereference($clnt->cl_xprt),
-                                        "struct rpc_xprt")->servername))
+       if (@defined($clnt->cl_server))
+               servername = __rpc_format_servername($clnt->cl_server,
+                                                    &$clnt->cl_xprt->addr)
+       else {
+               __xprt = rcu_dereference($clnt->cl_xprt)
+               servername = __rpc_format_servername(@cast(__xprt, "rpc_xprt")->servername,
+                                                    &@cast(__xprt, "rpc_xprt")->addr)
+       }
        progname = kernel_string(@choose_defined($clnt->cl_program->name,
                                                 $clnt->cl_protname))
        prog = prog_from_clnt($clnt)
@@ -498,9 +522,14 @@ probe sunrpc.clnt.call_sync.return = kernel.function("rpc_call_sync").return !,
 probe sunrpc.clnt.call_async = kernel.function("rpc_call_async") !,
        module("sunrpc").function("rpc_call_async")
 {
-       servername = kernel_string(@choose_defined($clnt->cl_server,
-                                  @cast(rcu_dereference($clnt->cl_xprt),
-                                        "struct rpc_xprt")->servername))
+       if (@defined($clnt->cl_server))
+               servername = __rpc_format_servername($clnt->cl_server,
+                                                    &$clnt->cl_xprt->addr)
+       else {
+               __xprt = rcu_dereference($clnt->cl_xprt)
+               servername = __rpc_format_servername(@cast(__xprt, "rpc_xprt")->servername,
+                                                    &@cast(__xprt, "rpc_xprt")->addr)
+       }
        progname = kernel_string(@choose_defined($clnt->cl_program->name,
                                                 $clnt->cl_protname))
        prog = prog_from_clnt($clnt)
@@ -543,9 +572,14 @@ probe sunrpc.clnt.call_async.return =
 probe sunrpc.clnt.restart_call = kernel.function("rpc_restart_call") !,
        module("sunrpc").function("rpc_restart_call")
 {
-       servername = kernel_string(@choose_defined($task->tk_client->cl_server,
-                                  @cast(rcu_dereference($task->tk_client->cl_xprt),
-                                        "struct rpc_xprt")->servername))
+       if (@defined($task->tk_client->cl_server))
+               servername = __rpc_format_servername($task->tk_client->cl_server,
+                                                    &$task->tk_client->cl_xprt->addr)
+       else {
+               __xprt = rcu_dereference($task->tk_client->cl_xprt)
+               servername = __rpc_format_servername(@cast(__xprt, "rpc_xprt")->servername,
+                                                    &@cast(__xprt, "rpc_xprt")->addr)
+       }
        prog = prog_from_clnt($task->tk_client)
        xid = $task->tk_rqstp->rq_xid
        tk_pid = $task->tk_pid
@@ -1190,3 +1224,33 @@ function addr_from_rqst_str:string(rqstp:long)
                          @cast(addr, "sockaddr_in6")->sin6_port)
 }
 
+%{
+#include <linux/un.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+%}
+
+function __rpc_format_servername:string(servername:long, address:long)
+{
+       printf("__rpc_format_servername: %p\n", servername)
+       if (servername != 0)
+               return kernel_string(servername)
+
+       // If 'servername' is NULL, create a string representation of
+       // the passed-in address.
+       // 
+       // Note that 'address' is a generic 'struct sockaddr'. When
+       // you use it you have to cast it to the more specific
+       // structure based on the family type.
+       if (@cast(address, "sockaddr")->sa_family == %{ /* pure */ /* unprivileged */ AF_LOCAL %}) {
+               return kernel_string(@cast(address, "sockaddr_un")->sun_path)
+       }
+       else if (@cast(address, "sockaddr")->sa_family == %{ /* pure */ /* unprivileged */ AF_INET %}) {
+               return format_ipaddr(&@cast(address, "sockaddr_in")->sin_addr->s_addr, %{ /* pure */ /* unprivileged */ AF_INET %})
+       }
+       else if (@cast(address, "sockaddr")->sa_family == %{ /* pure */ /* unprivileged */ AF_INET6 %}) {
+               return format_ipaddr(&@cast(address, "sockaddr_in6")->sin6_addr,
+                                    %{ /* pure */ /* unprivileged */ AF_INET6 %})
+       }
+       return "*unknown address family*"
+}
This page took 0.036071 seconds and 5 git commands to generate.