This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
RE: new syscall tapset checked in, but needs work
- From: "Stone, Joshua I" <joshua dot i dot stone at intel dot com>
- To: "Frank Ch. Eigler" <fche at redhat dot com>, "Martin Hunt" <hunt at redhat dot com>
- Cc: <systemtap at sources dot redhat dot com>
- Date: Wed, 1 Feb 2006 14:47:35 -0800
- Subject: RE: new syscall tapset checked in, but needs work
Frank Ch. Eigler wrote:
> hunt wrote:
>
>> [...] I'm using an strace-like output format for the args, although
>> that really isn't possible for things like sys_read() where strace
>> shows the results that get written in the input buffer. It is
>> possible to write a systemtap script to do that, but not at the
>> tapset level.
>
> If it is possible at the script level, it's possible at the tapset
> level (on purpose). For instance, a tapset alias for syscall.read
> could store away its incoming args in an private array, until its
> .return (until bug #1382 is done). All that code would be optimized
> away if not used.
Interesting idea - just to be explicit, is this what you had in mind?
# read _______________________________________________________
# ssize_t sys_read(unsigned int fd, char __user * buf, size_t count)
global __syscall_read_fd
global __syscall_read_buf
global __syscall_read_count
probe syscall.read = kernel.function("sys_read") {
name = "read"
__tid = tid()
fd = __syscall_read_fd[__tid] = $fd
buf_uaddr = __syscall_read_buf[__tid] = $buf
count = __syscall_read_count[__tid] = $count
argstr = sprintf("%d, ..., %d", fd, count)
}
probe syscall.read.return = kernel.function("sys_read").return {
name = "read"
__tid = tid()
fd = __syscall_read_fd[__tid]
buf_uaddr = __syscall_read_buf[__tid]
count = __syscall_read_count[__tid]
delete __syscall_read_fd[__tid]
delete __syscall_read_buf[__tid]
delete __syscall_read_count[__tid]
# at this point we
argstr = sprintf("%d, ..., %d", fd, count)
returnp = 1
}
Then person using the tapset would do something like:
probe syscall.read { /* capture arguments */ }
probe syscall.read.return {
printf("read(%s) = %s\n", argstr, errno_str(returnval()))
}
This only works if there's only one instance of the return probe, else
the args will be deleted too soon. If we don't delete the args though,
the map could fill quite easily.
By the way, I tried it without accessing the args, and the optimizer
didn't clean it up.
probe syscall.read { /* capture arguments */ }
probe syscall.read.return { }
I also notice this on testsuite/buildok/delete.stp - perhaps the
optimizer isn't handling delete statements?
Josh