This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug tapsets/16716] New: syscall wrappers causing syscall probes to get the wrong types


https://sourceware.org/bugzilla/show_bug.cgi?id=16716

            Bug ID: 16716
           Summary: syscall wrappers causing syscall probes to get the
                    wrong types
           Product: systemtap
           Version: unspecified
            Status: NEW
          Severity: normal
          Priority: P2
         Component: tapsets
          Assignee: systemtap at sourceware dot org
          Reporter: dsmith at redhat dot com

On newer kernels (like rawhide), the old HAVE_SYSCALL_WRAPPERS kernel config is
the default (in fact you can't turn it off). This is causing the syscall probes
to find the wrong types for syscall parameters. This causes the syscall probe
variables to return incorrect values, especially for negative values like '-1'.

Let's take the socket() syscall for example. From the user's point of view, it
looks like this:

====
int socket(int domain, int type, int protocol);                          
====

In RHEL6, stap thinks it looks like this:

====
# stap -L 'kernel.function("sys_socket").call'
kernel.function("sys_socket@net/socket.c:1319").call $family:int $type:int
$protocol:int $sock:struct socket*
====

The syscall.socket probe alias looks like this:

====
probe syscall.socket = kernel.function("sys_socket").call ?
{
        name = "socket"
        family = $family
        type = $type
        protocol = $protocol
        argstr = sprintf("%s, %s, %s", _sock_family_str($family),
                         _sock_type_str($type),
                         _sock_protocol_str($family, $protocol))
}
====

So, for RHEL6, things work as planned. When '$family' (for instance) is
assigned to 'family', stap looks up its DWARF type, which is in 32-bit integer.
So, a 32-bit integer gets assigned to 'family'. If that value happens to be -1,
it will get appropriately sign extended.

But, because of syscall wrappers getting turned on in new kernels, we have
this:

====
# stap -L 'kernel.function("sys_socket").call'
kernel.function("SyS_socket@net/socket.c:1378").call $family:long int
$type:long int $protocol:long int

For the syscall wrapper function 'sys_socket', all the parameters have been
made into 64-bit integers. So, when '$family' is assigned to 'family', stap
looks up its DWARF type, which is a 64-bit integer. Stap interprets the value
incorrectly (since it really isn't a 64-bit value), so we end up with
4294967295 instead of -1.

We could try probing the "real" syscall, SYSC_socket(), but:

====
# stap -L 'kernel.function("SYSC_socket").inline'
kernel.function("SYSC_socket@net/socket.c:1378").inline $type:int
====

gcc still doesn't produce great debuginfo for inline functions. In the case of
SYSC_socket(), we can only find $type - we can't find $family or $protocol.

Right now the only solution I know of is a manual process of changing the probe
aliases to fix the types:

====
probe syscall.socket = kernel.function("sys_socket").call ?
{
        name = "socket"
        family = __int32($family)
        type = __int32($type)
        protocol = __int32($protocol)
        argstr = sprintf("%s, %s, %s", _sock_family_str(family),
                         _sock_type_str(type),
                         _sock_protocol_str(family, protocol))
}
====

To fix this correctly, we'll need to add more testing to the syscall test suite
so that this stays fixed.

Ironically, the nd_syscall tapsets fare better here, since they don't infer
types from the debuginfo, but the types are hardcoded (although I have seen a
few similar problems there).

-- 
You are receiving this mail because:
You are the assignee for the bug.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]