From 588d5bdf6e9a711ce1228214007d04a3787fef7e Mon Sep 17 00:00:00 2001 From: David Smith Date: Thu, 19 Jun 2014 15:50:25 -0500 Subject: [PATCH] PR16716 partial fix: Fix types in '[nd_]syscall.eventfd'. * tapset/linux/syscalls.stp (syscall.eventfd): Better handle eventfd() vs. eventfd2(). Add 'count' and 'flags_str' convenience variables. Fix types. * tapset/linux/nd_syscalls.stp: Ditto. * tapset/linux/aux_syscalls.stp (_eventfd2_flag_str): Updated and improved. * runtime/linux/compat_unistd.h (__NR_compat_eventfd2): New define. * testsuite/systemtap.syscall/eventfd.c: Add more tests. * testsuite/buildok/syscalls-detailed.stp: Add tests for new convenience variables. * testsuite/buildok/nd_syscalls-detailed.stp: Ditto. --- runtime/linux/compat_unistd.h | 5 +++ tapset/linux/aux_syscalls.stp | 33 +++++++++-------- tapset/linux/nd_syscalls.stp | 30 +++++++-------- tapset/linux/syscalls.stp | 43 +++++++++++++++------- testsuite/buildok/nd_syscalls-detailed.stp | 2 +- testsuite/buildok/syscalls-detailed.stp | 2 +- testsuite/systemtap.syscall/eventfd.c | 17 ++++++++- 7 files changed, 82 insertions(+), 50 deletions(-) diff --git a/runtime/linux/compat_unistd.h b/runtime/linux/compat_unistd.h index 26f729cde..a2f9a31b8 100644 --- a/runtime/linux/compat_unistd.h +++ b/runtime/linux/compat_unistd.h @@ -66,6 +66,9 @@ #ifndef __NR_ia32_epoll_wait #define __NR_ia32_epoll_wait 256 #endif +#ifndef __NR_ia32_eventfd2 +#define __NR_ia32_eventfd2 328 +#endif #ifndef __NR_ia32_faccessat #define __NR_ia32_faccessat 307 #endif @@ -122,6 +125,7 @@ #define __NR_compat_close __NR_ia32_close #define __NR_compat_dup3 __NR_ia32_dup3 #define __NR_compat_epoll_wait __NR_ia32_epoll_wait +#define __NR_compat_eventfd2 __NR_ia32_eventfd2 #define __NR_compat_faccessat __NR_ia32_faccessat #define __NR_compat_fchmodat __NR_ia32_fchmodat #define __NR_compat_fchownat __NR_ia32_fchownat @@ -154,6 +158,7 @@ #define __NR_compat_close __NR_close #define __NR_compat_dup3 __NR_dup3 #define __NR_compat_epoll_wait __NR_epoll_wait +#define __NR_compat_eventfd2 __NR_eventfd2 #define __NR_compat_faccessat __NR_faccessat #define __NR_compat_fchmodat __NR_fchmodat #define __NR_compat_fchownat __NR_fchownat diff --git a/tapset/linux/aux_syscalls.stp b/tapset/linux/aux_syscalls.stp index 06b9fa599..ca6ad30f8 100644 --- a/tapset/linux/aux_syscalls.stp +++ b/tapset/linux/aux_syscalls.stp @@ -2487,24 +2487,25 @@ function _epoll_create1_flag_str:string(f:long) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) #include #endif -%} -function _eventfd2_flag_str:string(f:long) -%{ /* pure */ - long flags = STAP_ARG_f; - char *str = STAP_RETVALUE; - int len; - str[0] = '\0'; -#if defined(EFD_CLOEXEC) && defined(EFD_NONBLOCK) - if (flags & EFD_NONBLOCK) - strlcat(str, "EFD_NONBLOCK|", MAXSTRINGLEN); - if (flags & EFD_CLOEXEC) - strlcat(str, "EFD_CLOEXEC|", MAXSTRINGLEN); +static const _stp_val_array const _stp_eventfd2_flag_list[] = { +#ifdef EFD_NONBLOCK + V(EFD_NONBLOCK), #endif - - len = strlen(str); - if (len) - str[strlen(str)-1] = '\0'; +#ifdef EFD_CLOEXEC + V(EFD_CLOEXEC), +#endif +#ifdef EFD_SEMAPHORE + V(EFD_SEMAPHORE), +#endif + {0, NULL} +}; +%} +function _eventfd2_flag_str:string(flags:long) +%{ /* pure */ + uint32_t flags = (uint32_t)STAP_ARG_flags; + _stp_lookup_or_str(_stp_eventfd2_flag_list, flags, STAP_RETVALUE, + MAXSTRINGLEN); %} %{ diff --git a/tapset/linux/nd_syscalls.stp b/tapset/linux/nd_syscalls.stp index b1397b032..93b1c1d90 100644 --- a/tapset/linux/nd_syscalls.stp +++ b/tapset/linux/nd_syscalls.stp @@ -993,45 +993,41 @@ probe nd_syscall.epoll_wait.return = kprobe.function("compat_sys_epoll_wait").re # eventfd _____________________________________________________ # long sys_eventfd(unsigned int count) # SYSCALL_DEFINE2(eventfd2, unsigned int, count, int, flags) -probe nd_syscall.eventfd = __nd_syscall.eventfd2 !, - __nd_syscall.eventfd ? +probe nd_syscall.eventfd = __nd_syscall.eventfd2 ?, __nd_syscall.eventfd ? { } probe __nd_syscall.eventfd2 = kprobe.function("sys_eventfd2") { + @__syscall_compat_gate(%{ __NR_eventfd2 %}, %{ __NR_compat_eventfd2 %}) + name = "eventfd2" asmlinkage() + count = uint_arg(1) flags = int_arg(2) - if (flags == 0) { - name = "eventfd" - argstr = sprint(uint_arg(1)) - } else { - name = "eventfd2" - argstr = sprintf("%d, %s", uint_arg(1), - _eventfd2_flag_str(flags)) - } + flags_str = _eventfd2_flag_str(flags) + argstr = sprintf("%u, %s", count, flags_str) } probe __nd_syscall.eventfd = kprobe.function("sys_eventfd") { name = "eventfd" asmlinkage() + count = uint_arg(1) flags = 0 - argstr = sprint(uint_arg(1)) + flags_str = "0x0" + argstr = sprint(count) } -probe nd_syscall.eventfd.return = __nd_syscall.eventfd2.return !, +probe nd_syscall.eventfd.return = __nd_syscall.eventfd2.return ?, __nd_syscall.eventfd.return ? { + retstr = returnstr(1) } probe __nd_syscall.eventfd2.return = kprobe.function("sys_eventfd2").return { - flags = @entry(__asmlinkage_int_arg(2)) - name = flags == 0 ? "eventfd" : "eventfd2" - retstr = returnstr(1) + @__syscall_compat_gate(%{ __NR_eventfd2 %}, %{ __NR_compat_eventfd2 %}) + name = "eventfd2" } probe __nd_syscall.eventfd.return = kprobe.function("sys_eventfd").return { - flags = 0 name = "eventfd" - retstr = returnstr(1) } # execve _____________________________________________________ diff --git a/tapset/linux/syscalls.stp b/tapset/linux/syscalls.stp index faf09c2c7..9975b90bb 100644 --- a/tapset/linux/syscalls.stp +++ b/tapset/linux/syscalls.stp @@ -905,25 +905,40 @@ probe syscall.epoll_wait.return = kernel.function("compat_sys_epoll_wait").retur # eventfd _____________________________________________________ # long sys_eventfd(unsigned int count) # SYSCALL_DEFINE2(eventfd2, unsigned int, count, int, flags) -probe syscall.eventfd = kernel.function("sys_eventfd2").call !, - kernel.function("sys_eventfd").call ? +probe syscall.eventfd = __syscall.eventfd2 ?, __syscall.eventfd ? { - flags = @choose_defined($flags, 0) - if (flags == 0) { - name = "eventfd" - argstr = sprint($count) - } else { - name = "eventfd2" - argstr = sprintf("%d, %s", $count, _eventfd2_flag_str(flags)) - } } -probe syscall.eventfd.return = kernel.function("sys_eventfd2").return !, - kernel.function("sys_eventfd").return ? +probe __syscall.eventfd2 = kernel.function("sys_eventfd2").call +{ + @__syscall_compat_gate(%{ __NR_eventfd2 %}, %{ __NR_compat_eventfd2 %}) + name = "eventfd2" + count = __uint32($count) + flags = __int32($flags) + flags_str = _eventfd2_flag_str(flags) + argstr = sprintf("%u, %s", count, _eventfd2_flag_str(flags)) +} +probe __syscall.eventfd = kernel.function("sys_eventfd").call +{ + name = "eventfd" + count = __uint32($count) + flags = 0 + flags_str = "0x0" + argstr = sprint(count) +} +probe syscall.eventfd.return = __syscall.eventfd2.return ?, + __syscall.eventfd.return ? { - flags = @choose_defined($flags, 0) - name = flags == 0 ? "eventfd" : "eventfd2" retstr = return_str(1, $return) } +probe __syscall.eventfd2.return = kernel.function("sys_eventfd2").return +{ + @__syscall_compat_gate(%{ __NR_eventfd2 %}, %{ __NR_compat_eventfd2 %}) + name = "eventfd2" +} +probe __syscall.eventfd.return = kernel.function("sys_eventfd").return +{ + name = "eventfd" +} # execve _____________________________________________________ # NB: kprocess.exec[_complete] is aliased to syscall.execve[.return] diff --git a/testsuite/buildok/nd_syscalls-detailed.stp b/testsuite/buildok/nd_syscalls-detailed.stp index 24074f855..4eb57b70b 100755 --- a/testsuite/buildok/nd_syscalls-detailed.stp +++ b/testsuite/buildok/nd_syscalls-detailed.stp @@ -325,7 +325,7 @@ probe nd_syscall.epoll_wait.return ? probe nd_syscall.eventfd ? { printf("%s, %s\n", name, argstr) - printf("%d\n", flags) + printf("%u, %d, %s\n", count, flags, flags_str) } probe nd_syscall.eventfd.return ? { diff --git a/testsuite/buildok/syscalls-detailed.stp b/testsuite/buildok/syscalls-detailed.stp index b7f552993..881c20dfd 100755 --- a/testsuite/buildok/syscalls-detailed.stp +++ b/testsuite/buildok/syscalls-detailed.stp @@ -325,7 +325,7 @@ probe syscall.epoll_wait.return ? probe syscall.eventfd ? { printf("%s, %s\n", name, argstr) - printf("%d\n", flags) + printf("%u, %d, %s\n", count, flags, flags_str) } probe syscall.eventfd.return ? { diff --git a/testsuite/systemtap.syscall/eventfd.c b/testsuite/systemtap.syscall/eventfd.c index f204ddeba..d59a79183 100644 --- a/testsuite/systemtap.syscall/eventfd.c +++ b/testsuite/systemtap.syscall/eventfd.c @@ -1,10 +1,11 @@ /* COVERAGE: eventfd eventfd2 */ #include +#include int main() { int fd = eventfd(0, 0); - //staptest// eventfd (0) = NNNN + //staptest// eventfd[2]? (0[[[[, 0x0]]]]?) = NNNN #ifdef EFD_NONBLOCK fd = eventfd(1, EFD_NONBLOCK); @@ -17,5 +18,19 @@ int main() //staptest// eventfd2 (3, EFD_NONBLOCK|EFD_CLOEXEC) = NNNN #endif + fd = eventfd(-1, 0); + //staptest// eventfd[2]? (4294967295[[[[, 0x0]]]]?) = NNNN + + fd = eventfd(4, -1); + //staptest// eventfd2 (4, EFD_[^ ]+|XXXX) = -NNNN (EINVAL) + + // Try to force an eventfd() (as opposed to a eventfd2()) syscall. +#ifdef SYS_eventfd + syscall(SYS_eventfd, 5); + //staptest// eventfd (5) = NNNN + + syscall(SYS_eventfd, -1); + //staptest// eventfd (4294967295) = NNNN +#endif return 0; } -- 2.43.5