From cd87311b90a49345f0da704ea376c75230d92162 Mon Sep 17 00:00:00 2001 From: David Smith Date: Wed, 9 Apr 2014 12:00:05 -0500 Subject: [PATCH] PR16716: Fix types in syscall.sched_{getscheduler,setscheduler,rr_get_interval} * tapset/linux/syscalls2.stp (syscall.sched_getscheduler): Fixed types. (syscall.sched_setscheduler): Ditto. (syscall.sched_rr_get_interval): Fixed nesting and types. Also change 'argstr' to just have a pointer to the 'struct timespec' value, since that is an output parameter and decoding it on input won't produce anything of value. * tapset/linux/nd_syscalls2.stp: Ditto. * tapset/linux/aux_syscalls.stp (_sched_policy_str): Updated to handle new values, including the new SCHED_RESET_ON_FORK flag. * testsuite/systemtap.syscall/test.tcl (run_one_test): Since execname() only returns the first 15 characters of the test program name, truncate it. * testsuite/systemtap.syscall/sched_getscheduler.c: New testcase * testsuite/systemtap.syscall/sched_rr_get_interval.c: Ditto. * testsuite/systemtap.syscall/sched_setscheduler.c: Ditto. --- tapset/linux/aux_syscalls.stp | 39 +++++++++++++++---- tapset/linux/nd_syscalls2.stp | 21 ++++++++-- tapset/linux/syscalls2.stp | 36 ++++++++++++----- .../systemtap.syscall/sched_getscheduler.c | 19 +++++++++ .../systemtap.syscall/sched_rr_get_interval.c | 29 ++++++++++++++ .../systemtap.syscall/sched_setscheduler.c | 38 ++++++++++++++++++ testsuite/systemtap.syscall/test.tcl | 7 +++- 7 files changed, 167 insertions(+), 22 deletions(-) create mode 100644 testsuite/systemtap.syscall/sched_getscheduler.c create mode 100644 testsuite/systemtap.syscall/sched_rr_get_interval.c create mode 100644 testsuite/systemtap.syscall/sched_setscheduler.c diff --git a/tapset/linux/aux_syscalls.stp b/tapset/linux/aux_syscalls.stp index b298bfb3b..5fee958fa 100644 --- a/tapset/linux/aux_syscalls.stp +++ b/tapset/linux/aux_syscalls.stp @@ -1315,13 +1315,38 @@ function _module_flags_str:string(flags:long) str[strlen(str)-1] = '\0'; %} -function _sched_policy_str(policy) { - if(policy==0) return "SCHED_OTHER" - if(policy==1) return "SCHED_FIFO" - if(policy==2) return "SCHED_RR" - if(policy==3) return "SCHED_BATCH" - return sprintf("UNKNOWN VALUE: %d", policy) -} +%{ +#include + +static const _stp_val_array const _stp_sched_policy_list[] = { + {SCHED_NORMAL, "SCHED_OTHER"}, // SCHED_NORMAL==SCHED_OTHER + V(SCHED_FIFO), + V(SCHED_RR), + V(SCHED_BATCH), +#ifdef SCHED_IDLE + V(SCHED_IDLE), +#endif +#ifdef SCHED_DEADLINE + V(SCHED_DEADLINE), +#endif + {0, NULL} +}; +%} + +function _sched_policy_str(policy) +%{ + unsigned int policy = (unsigned int)STAP_ARG_policy; +#ifdef SCHED_RESET_ON_FORK + int reset_on_fork = (policy & SCHED_RESET_ON_FORK); + policy &= ~SCHED_RESET_ON_FORK; +#endif + _stp_lookup_str(_stp_sched_policy_list, policy, STAP_RETVALUE, + MAXSTRINGLEN); +#ifdef SCHED_RESET_ON_FORK + if (reset_on_fork) + strlcat(STAP_RETVALUE, "|SCHED_RESET_ON_FORK", MAXSTRINGLEN); +#endif +%} function _priority_which_str(which) { if(which==0) return "PRIO_PROCESS" diff --git a/tapset/linux/nd_syscalls2.stp b/tapset/linux/nd_syscalls2.stp index 8f2bd70b8..92492625d 100644 --- a/tapset/linux/nd_syscalls2.stp +++ b/tapset/linux/nd_syscalls2.stp @@ -1689,19 +1689,34 @@ probe nd_syscall.sched_getscheduler.return = kprobe.function("sys_sched_getsched # # long sys_sched_rr_get_interval(pid_t pid, struct timespec __user *interval) # -probe nd_syscall.sched_rr_get_interval = kprobe.function("sys_sched_rr_get_interval") ? +probe nd_syscall.sched_rr_get_interval = __nd_syscall.sched_rr_get_interval, + kprobe.function("compat_sys_sched_rr_get_interval").call ?, + kprobe.function("sys32_sched_rr_get_interval").call ? { name = "sched_rr_get_interval" asmlinkage() pid = int_arg(1) tp_uaddr = pointer_arg(2) - argstr = sprintf("%d, %s", pid, _struct_timespec_u(tp_uaddr, 1)) + argstr = sprintf("%d, %p", pid, tp_uaddr) } -probe nd_syscall.sched_rr_get_interval.return = kprobe.function("sys_sched_rr_get_interval").return ? +probe __nd_syscall.sched_rr_get_interval = + kprobe.function("sys_sched_rr_get_interval").call +{ + @__syscall_gate(%{ __NR_sched_rr_get_interval %}) +} +probe nd_syscall.sched_rr_get_interval.return = + __nd_syscall.sched_rr_get_interval.return, + kprobe.function("compat_sys_sched_rr_get_interval").return ?, + kernel.function("sys32_sched_rr_get_interval").return ? { name = "sched_rr_get_interval" retstr = returnstr(1) } +probe __nd_syscall.sched_rr_get_interval.return = + kprobe.function("sys_sched_rr_get_interval").return +{ + @__syscall_gate(%{ __NR_sched_rr_get_interval %}) +} # sched_setaffinity __________________________________________ # long sys_sched_setaffinity(pid_t pid, diff --git a/tapset/linux/syscalls2.stp b/tapset/linux/syscalls2.stp index ce1b2d084..8cc829620 100644 --- a/tapset/linux/syscalls2.stp +++ b/tapset/linux/syscalls2.stp @@ -1676,30 +1676,46 @@ probe syscall.sched_get_priority_min.return = kernel.function("sys_sched_get_pri probe syscall.sched_getscheduler = kernel.function("sys_sched_getscheduler").call { name = "sched_getscheduler" - pid = $pid - argstr = sprint($pid) + pid = __int32($pid) + argstr = sprint(pid) } probe syscall.sched_getscheduler.return = kernel.function("sys_sched_getscheduler").return { name = "sched_getscheduler" retstr = return_str(1, $return) } + # sched_rr_get_interval ______________________________________ # # long sys_sched_rr_get_interval(pid_t pid, struct timespec __user *interval) # -probe syscall.sched_rr_get_interval = kernel.function("sys_sched_rr_get_interval").call +probe syscall.sched_rr_get_interval = __syscall.sched_rr_get_interval, + kernel.function("compat_sys_sched_rr_get_interval").call ?, + kernel.function("sys32_sched_rr_get_interval").call ? { name = "sched_rr_get_interval" - pid = $pid + pid = __int32($pid) tp_uaddr = $interval - argstr = sprintf("%d, %s", $pid, _struct_timespec_u($interval, 1)) + argstr = sprintf("%d, %p", pid, $interval) +} +probe __syscall.sched_rr_get_interval = + kernel.function("sys_sched_rr_get_interval").call +{ + @__syscall_gate(%{ __NR_sched_rr_get_interval %}) } -probe syscall.sched_rr_get_interval.return = kernel.function("sys_sched_rr_get_interval").return +probe syscall.sched_rr_get_interval.return = + __syscall.sched_rr_get_interval.return, + kernel.function("compat_sys_sched_rr_get_interval").return ?, + kernel.function("sys32_sched_rr_get_interval").return ? { name = "sched_rr_get_interval" retstr = return_str(1, $return) } +probe __syscall.sched_rr_get_interval.return = + kernel.function("sys_sched_rr_get_interval").return +{ + @__syscall_gate(%{ __NR_sched_rr_get_interval %}) +} # sched_setaffinity __________________________________________ # long sys_sched_setaffinity(pid_t pid, @@ -1744,11 +1760,11 @@ probe syscall.sched_setparam.return = kernel.function("sys_sched_setparam").retu probe syscall.sched_setscheduler = kernel.function("sys_sched_setscheduler").call ? { name = "sched_setscheduler" - pid = $pid - policy = $policy - policy_str = _sched_policy_str($policy) + pid = __int32($pid) + policy = __int32($policy) + policy_str = _sched_policy_str(policy) p_uaddr = $param - argstr = sprintf("%d, %s, %p", $pid, policy_str, $param) + argstr = sprintf("%d, %s, %p", pid, policy_str, $param) } probe syscall.sched_setscheduler.return = kernel.function("sys_sched_setscheduler").return ? { diff --git a/testsuite/systemtap.syscall/sched_getscheduler.c b/testsuite/systemtap.syscall/sched_getscheduler.c new file mode 100644 index 000000000..f425ef09e --- /dev/null +++ b/testsuite/systemtap.syscall/sched_getscheduler.c @@ -0,0 +1,19 @@ +/* COVERAGE: sched_getscheduler */ + +#include +#include +#include + +int main() +{ + sched_getscheduler(0); + //staptest// sched_getscheduler (0) = 0 + + sched_getscheduler((pid_t)-1); + //staptest// sched_getscheduler (-1) = -NNNN (EINVAL) + + sched_getscheduler(999999); + //staptest// sched_getscheduler (999999) = -NNNN (ESRCH) + + return 0; +} diff --git a/testsuite/systemtap.syscall/sched_rr_get_interval.c b/testsuite/systemtap.syscall/sched_rr_get_interval.c new file mode 100644 index 000000000..3f4c43017 --- /dev/null +++ b/testsuite/systemtap.syscall/sched_rr_get_interval.c @@ -0,0 +1,29 @@ +/* COVERAGE: sched_rr_get_interval */ + +#define _GNU_SOURCE +#include +#include +#include + +int main() +{ + struct timespec tp; + + sched_rr_get_interval(0, &tp); + //staptest// sched_rr_get_interval (0, XXXX) = 0 + + sched_rr_get_interval(-1, &tp); + //staptest// sched_rr_get_interval (-1, XXXX) = -NNNN (EINVAL) + + sched_rr_get_interval(999999, &tp); + //staptest// sched_rr_get_interval (999999, XXXX) = -NNNN (ESRCH) + + sched_rr_get_interval(0, (struct timespec *)-1); +#ifdef __s390__ + //staptest// sched_rr_get_interval (0, 0x[7]?[f]+) = -NNNN (EFAULT) +#else + //staptest// sched_rr_get_interval (0, 0x[f]+) = -NNNN (EFAULT) +#endif + + return 0; +} diff --git a/testsuite/systemtap.syscall/sched_setscheduler.c b/testsuite/systemtap.syscall/sched_setscheduler.c new file mode 100644 index 000000000..2fa8652ca --- /dev/null +++ b/testsuite/systemtap.syscall/sched_setscheduler.c @@ -0,0 +1,38 @@ +/* COVERAGE: sched_setscheduler */ + +#define _GNU_SOURCE +#include +#include +#include + +int main() +{ + struct sched_param param; + + sched_setscheduler(999999, SCHED_OTHER, ¶m); + //staptest// sched_setscheduler (999999, SCHED_OTHER, XXXX) = -NNNN (ESRCH) + + sched_setscheduler(-1, SCHED_FIFO, ¶m); + //staptest// sched_setscheduler (-1, SCHED_FIFO, XXXX) = -NNNN (EINVAL) + +#ifdef SCHED_RESET_ON_FORK + sched_setscheduler(0, SCHED_FIFO|SCHED_RESET_ON_FORK, ¶m); + //staptest// sched_setscheduler (0, SCHED_FIFO|SCHED_RESET_ON_FORK, XXXX) = -NNNN (EINVAL) +#endif + + sched_setscheduler(0, -1, ¶m); +#ifdef SCHED_RESET_ON_FORK + //staptest// sched_setscheduler (0, 0xbfffffff|SCHED_RESET_ON_FORK, XXXX) = -NNNN (EINVAL) +#else + //staptest// sched_setscheduler (0, 0xffffffff, XXXX) = -NNNN (EINVAL) +#endif + + sched_setscheduler(0, SCHED_OTHER, (struct sched_param *)-1); +#ifdef __s390__ + //staptest// sched_setscheduler (0, SCHED_OTHER, 0x[7]?[f]+) = -NNNN (EFAULT) +#else + //staptest// sched_setscheduler (0, SCHED_OTHER, 0x[f]+) = -NNNN (EFAULT) +#endif + + return 0; +} diff --git a/testsuite/systemtap.syscall/test.tcl b/testsuite/systemtap.syscall/test.tcl index 6b7436423..7ad198ca4 100644 --- a/testsuite/systemtap.syscall/test.tcl +++ b/testsuite/systemtap.syscall/test.tcl @@ -31,6 +31,9 @@ proc run_one_test {filename flags bits suite} { set testname [file tail [string range $filename 0 end-2]] + # execname() returns the first 15 chars of the test exe name. + set re_testname [string range $testname 0 14] + if {[catch {exec mktemp -d [pwd]/staptestXXXXXX} syscall_dir]} { send_log "$bits-bit $testname $suite : Failed to create temporary directory: $syscall_dir" untested "$bits-bit $testname $suite" @@ -67,7 +70,7 @@ proc run_one_test {filename flags bits suite} { set ind 0 foreach line [split $output "\n"] { if {[regsub {//staptest//} $line {} line]} { - set line "$testname: [string trimleft $line]" + set line "$re_testname: [string trimleft $line]" # We need to quote all these metacharacters regsub -all {\(} $line {\\(} line @@ -127,7 +130,7 @@ proc run_one_test {filename flags bits suite} { send_log "RESULTS: (\'*\' = MATCHED EXPECTED)\n" set i 0 foreach line [split $output "\n"] { - if {[regexp "${testname}: " $line]} { + if {[regexp "${re_testname}: " $line]} { if {[regexp $results($i) $line]} { send_log "*$line\n" incr i -- 2.43.5