This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
[Bug tapsets/16716] New: syscall wrappers causing syscall probes to get the wrong types
- From: "dsmith at redhat dot com" <sourceware-bugzilla at sourceware dot org>
- To: systemtap at sourceware dot org
- Date: Mon, 17 Mar 2014 15:58:19 +0000
- Subject: [Bug tapsets/16716] New: syscall wrappers causing syscall probes to get the wrong types
- Auto-submitted: auto-generated
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.