From 9f61c5d4c3487aa8225d5271c798f5ebaafc398a Mon Sep 17 00:00:00 2001 From: David Smith Date: Mon, 2 Nov 2009 12:51:12 -0600 Subject: [PATCH] PR 6691 fixed by adding support for sys_accept4. * tapset/aux_syscalls.stp(_sock_type_str): Rewrote in embedded-C and added socket flags support. (_sock_flags_str): New function. * tapset/syscalls.stp: syscall.accept prefers to use sys_accept4 when it exists. Added support for sys_accept4's 'flag' parameter. * testsuite/systemtap.syscall/net1.c (main): Updated regular expression to handle the new 'flags' argument. --- tapset/aux_syscalls.stp | 80 ++++++++++++++++++++++++++---- tapset/syscalls.stp | 22 ++++++-- testsuite/systemtap.syscall/net1.c | 2 +- 3 files changed, 88 insertions(+), 16 deletions(-) diff --git a/tapset/aux_syscalls.stp b/tapset/aux_syscalls.stp index 9347e46f3..2f19ab163 100644 --- a/tapset/aux_syscalls.stp +++ b/tapset/aux_syscalls.stp @@ -1302,16 +1302,76 @@ function _sock_family_str(f) { return sprintf("UNKNOWN VALUE: %d", f) } -function _sock_type_str(t) { - if(t==1) return "SOCK_STREAM" - if(t==2) return "SOCK_DGRAM" - if(t==5) return "SOCK_SEQPACKET" - if(t==3) return "SOCK_RAW" - if(t==4) return "SOCK_RDM" - if(t==6) return "SOCK_DCCP" - if(t==10) return "SOCK_PACKET" - return sprintf("UNKNOWN VALUE: %d", t) -} +function _sock_type_str:string(type:long) +%{ /* pure */ +#ifdef SOCK_TYPE_MASK + int flags = (int)THIS->type & ~SOCK_TYPE_MASK; + int t = (int)THIS->type & SOCK_TYPE_MASK; +#else + int t = (int)THIS->type; +#endif + + switch (t) { + case SOCK_STREAM: + strlcpy (THIS->__retvalue, "SOCK_STREAM", MAXSTRINGLEN); + break; + case SOCK_DGRAM: + strlcpy (THIS->__retvalue, "SOCK_DGRAM", MAXSTRINGLEN); + break; + case SOCK_RAW: + strlcpy (THIS->__retvalue, "SOCK_RAW", MAXSTRINGLEN); + break; + case SOCK_RDM: + strlcpy (THIS->__retvalue, "SOCK_RDM", MAXSTRINGLEN); + break; + case SOCK_SEQPACKET: + strlcpy (THIS->__retvalue, "SOCK_SEQPACKET", MAXSTRINGLEN); + break; +#ifdef SOL_DCCP + case SOCK_DCCP: + strlcpy (THIS->__retvalue, "SOCK_DCCP", MAXSTRINGLEN); + break; +#endif + case SOCK_PACKET: + strlcpy (THIS->__retvalue, "SOCK_PACKET", MAXSTRINGLEN); + break; + default: + strlcpy (THIS->__retvalue, "UNKNOWN VALUE: %d", t); + break; + } + +#ifdef SOCK_TYPE_MASK + if (flags & SOCK_CLOEXEC) { + strlcat (THIS->__retvalue, "|SOCK_CLOEXEC", MAXSTRINGLEN); + } + if (flags & SOCK_NONBLOCK) { + strlcat (THIS->__retvalue, "|SOCK_NONBLOCK", MAXSTRINGLEN); + } +#endif +%} + +function _sock_flags_str:string(f:long) +%{ /* pure */ +#ifdef SOCK_TYPE_MASK + int flags = (int)THIS->f; + int len; + + THIS->__retvalue[0] = '\0'; + if (flags & SOCK_CLOEXEC) { + strlcat (THIS->__retvalue, "SOCK_CLOEXEC|", MAXSTRINGLEN); + } + if (flags & SOCK_NONBLOCK) { + strlcat (THIS->__retvalue, "SOCK_NONBLOCK|", MAXSTRINGLEN); + } + len = strlen(THIS->__retvalue); + if (len) { + THIS->__retvalue[len - 1] = '\0'; + } + else { + strlcat (THIS->__retvalue, "0", MAXSTRINGLEN); + } +#endif +%} function _opoll_op_str(o) { if(o==1) return "EPOLL_CTL_ADD" diff --git a/tapset/syscalls.stp b/tapset/syscalls.stp index 825842a62..dde0ca9fd 100644 --- a/tapset/syscalls.stp +++ b/tapset/syscalls.stp @@ -27,17 +27,29 @@ # accept _____________________________________________________ # long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, -# int __user *upeer_addrlen) -probe syscall.accept = kernel.function("SyS_accept").call !, - kernel.function("sys_accept").call ? +# int __user *upeer_addrlen, int flags) +probe syscall.accept = _syscall.accept4 !, _syscall.accept { name = "accept" sockfd = $fd addr_uaddr = $upeer_sockaddr addrlen_uaddr = $upeer_addrlen - argstr = sprintf("%d, %p, %p", $fd, $upeer_sockaddr, $upeer_addrlen) + argstr = sprintf("%d, %p, %p, %s", $fd, $upeer_sockaddr, + $upeer_addrlen, flags_str) } -probe syscall.accept.return = kernel.function("SyS_accept").return !, +probe _syscall.accept4 = kernel.function("sys_accept4").call +{ + flags = $flags + flags_str = _sock_flags_str($flags) +} +probe _syscall.accept = kernel.function("SyS_accept").call !, + kernel.function("sys_accept").call ? +{ + flags = 0 + flags_str = "0" +} +probe syscall.accept.return = kernel.function("sys_accept4").return !, + kernel.function("SyS_accept").return !, kernel.function("sys_accept").return ? { name = "accept" diff --git a/testsuite/systemtap.syscall/net1.c b/testsuite/systemtap.syscall/net1.c index f8079ffd9..b7f1d6cb9 100644 --- a/testsuite/systemtap.syscall/net1.c +++ b/testsuite/systemtap.syscall/net1.c @@ -32,7 +32,7 @@ int main() //staptest// listen (NNNN, 7) = 0 cfd = accept(listenfd, (struct sockaddr *)NULL, NULL); - //staptest// accept (NNNN, 0x[0]+, 0x[0]+) = -NNNN (EAGAIN) + //staptest// accept (NNNN, 0x[0]+, 0x[0]+, 0) = -NNNN (EAGAIN) close(cfd); close(listenfd); -- 2.43.5