]> sourceware.org Git - systemtap.git/commitdiff
PR18337: Test coverage improvements, tapset extension.
authorMartin Cermak <mcermak@redhat.com>
Tue, 28 Apr 2015 04:45:02 +0000 (06:45 +0200)
committerMartin Cermak <mcermak@redhat.com>
Tue, 28 Apr 2015 04:45:02 +0000 (06:45 +0200)
* tapset/linux/aux_syscalls.stp: New auxiliary function _kexec_flags_str()
* tapset/linux/nd_syscalls.stp: Fix types and nesting for kexec_load
* tapset/linux/syscalls.stp: Likewise
* testsuite/buildok/nd_syscalls-detailed.stp: Test the flags_str variable
* testsuite/buildok/syscalls-detailed.stp: Likewise
* testsuite/systemtap.syscall/kexec_load.c: New testcase
* testsuite/systemtap.syscall/set_tid_address.c: New testcase

tapset/linux/aux_syscalls.stp
tapset/linux/nd_syscalls.stp
tapset/linux/syscalls.stp
testsuite/buildok/nd_syscalls-detailed.stp
testsuite/buildok/syscalls-detailed.stp
testsuite/systemtap.syscall/kexec_load.c [new file with mode: 0644]
testsuite/systemtap.syscall/set_tid_address.c [new file with mode: 0644]

index caaa76b88a6c54196870aee1d456df01df38d57f..a46e3d8ba4e984595e03ffea0f55f49e90fce8ae 100644 (file)
@@ -5595,3 +5595,38 @@ function _struct_sysinfo_u:string(uaddr:long)
                }
        }
 %}
+
+%{
+#include <linux/kexec.h>
+static const _stp_val_array const _stp_kexec_flags_list[] = {
+       V(KEXEC_ON_CRASH),
+#ifdef KEXEC_PRESERVE_CONTEXT
+       V(KEXEC_PRESERVE_CONTEXT),
+#endif
+       V(KEXEC_ARCH_DEFAULT),
+       V(KEXEC_ARCH_386),
+       V(KEXEC_ARCH_X86_64),
+       V(KEXEC_ARCH_PPC),
+       V(KEXEC_ARCH_PPC64),
+       V(KEXEC_ARCH_IA_64),
+#ifdef KEXEC_ARCH_ARM
+       V(KEXEC_ARCH_ARM),
+#endif
+       V(KEXEC_ARCH_S390),
+       V(KEXEC_ARCH_SH),
+#ifdef KEXEC_ARCH_MIPS_LE
+       V(KEXEC_ARCH_MIPS_LE),
+#endif
+#ifdef KEXEC_ARCH_MIPS
+       V(KEXEC_ARCH_MIPS),
+#endif
+       {0, NULL}
+};
+%}
+
+function _kexec_flags_str:string(flags:long)
+%{ /* pure */
+       unsigned long flags = (unsigned int)STAP_ARG_flags;
+       _stp_lookup_or_str(_stp_kexec_flags_list, flags, STAP_RETVALUE, MAXSTRINGLEN);
+%}
+
index a1c076e2e69cdbecd61647a022f0b8995070b217..11589cd79ec5aaa6f367ac59cee0a0094bb184cb 100644 (file)
@@ -3032,8 +3032,8 @@ probe nd_syscall.ioprio_set.return = kprobe.function("sys_ioprio_set").return ?
 #              struct compat_kexec_segment __user *segments,
 #              unsigned long flags)
 #
-probe nd_syscall.kexec_load = kprobe.function("compat_sys_kexec_load") ?,
-                              kprobe.function("sys_kexec_load") ?
+probe nd_syscall.kexec_load = __nd_syscall.kexec_load ?,
+                              kprobe.function("compat_sys_kexec_load") ?
 {
        name = "kexec_load"
        asmlinkage()
@@ -3041,14 +3041,23 @@ probe nd_syscall.kexec_load = kprobe.function("compat_sys_kexec_load") ?,
        nr_segments = ulong_arg(2)
        segments_uaddr = pointer_arg(3)
        flags = ulong_arg(4)
-       argstr = sprintf("%p, %d, %p, %d", entry, nr_segments, segments_uaddr, flags)
+       flags_str = _kexec_flags_str(flags)
+       argstr = sprintf("%p, %u, %p, %s", entry, nr_segments, segments_uaddr, flags_str)
 }
-probe nd_syscall.kexec_load.return = kprobe.function("compat_sys_kexec_load").return ?,
-                                     kprobe.function("sys_kexec_load").return ?
+probe __nd_syscall.kexec_load = kprobe.function("sys_kexec_load")
+{
+       @__syscall_gate_compat_simple
+}
+probe nd_syscall.kexec_load.return = __nd_syscall.kexec_load.return ?,
+                                     kprobe.function("compat_sys_kexec_load").return ?
 {
        name = "kexec_load"
        retstr = returnstr(1)
 }
+probe __nd_syscall.kexec_load.return = kprobe.function("sys_kexec_load").return
+{
+       @__syscall_gate_compat_simple
+}
 
 # keyctl _____________________________________________________
 # long sys_keyctl(int option,
index 39e5dca156df286fbbe71fb34978ecb27b0112cf..d2cd10ac543d995905a9c4f1d834eb44fb79c1dc 100644 (file)
@@ -2842,22 +2842,31 @@ probe syscall.ioprio_set.return = kernel.function("sys_ioprio_set").return ?
 #              struct compat_kexec_segment __user *segments,
 #              unsigned long flags)
 #
-probe syscall.kexec_load = kernel.function("compat_sys_kexec_load").call ?,
-                           kernel.function("sys_kexec_load").call ?
+probe syscall.kexec_load = __syscall.kexec_load.call,
+                           kernel.function("compat_sys_kexec_load").call ?
 {
        name = "kexec_load"
-       entry = $entry
-       nr_segments = $nr_segments
+       entry = __ulong($entry)
+       nr_segments = __ulong($nr_segments)
        segments_uaddr = $segments
-       flags = $flags
-       argstr = sprintf("%p, %d, %p, %d", $entry, $nr_segments, $segments, $flags)
+       flags = __ulong($flags)
+       flags_str = _kexec_flags_str(flags)
+       argstr = sprintf("%p, %u, %p, %s", entry, nr_segments, segments_uaddr, flags_str)
+}
+probe __syscall.kexec_load.call = kernel.function("sys_kexec_load").call
+{
+       @__syscall_gate_compat_simple
 }
-probe syscall.kexec_load.return = kernel.function("compat_sys_kexec_load").return ?,
-                                  kernel.function("sys_kexec_load").return ?
+probe syscall.kexec_load.return = __syscall.syscall.kexec_load.return,
+                                  kernel.function("compat_sys_kexec_load").return ?
 {
        name = "kexec_load"
        retstr = return_str(1, $return)
 }
+probe __syscall.syscall.kexec_load.return = kernel.function("sys_kexec_load").return
+{
+       @__syscall_gate_compat_simple
+}
 
 # keyctl _____________________________________________________
 # long sys_keyctl(int option,
index 6ffda76dbca58ade9ef3a3bbda9b90989fb803bc..b0f37183dce378cca4a160dc47f794f46fbab78b 100755 (executable)
@@ -1037,7 +1037,8 @@ probe nd_syscall.ioprio_set.return ?
 probe nd_syscall.kexec_load ?
 {
        printf("%s, %s\n", name, argstr)
-       printf("%d, %d, %p, %d\n", entry, nr_segments, segments_uaddr, flags)
+       printf("%d, %u, %p, %d, %s\n", entry, nr_segments, segments_uaddr,
+               flags, flags_str)
 }
 probe nd_syscall.kexec_load.return ?
 {
index 7d35d540ac19852c194ceb40b4c1ff0262ba108d..01b9291eeb7f1b8100d016ec63fdbb7fdc90f6cb 100755 (executable)
@@ -1035,7 +1035,8 @@ probe syscall.ioprio_set.return ?
 probe syscall.kexec_load ?
 {
        printf("%s, %s\n", name, argstr)
-       printf("%d, %d, %p, %d\n", entry, nr_segments, segments_uaddr, flags)
+       printf("%d, %u, %p, %d, %s\n", entry, nr_segments, segments_uaddr,
+               flags, flags_str)
 }
 probe syscall.kexec_load.return ?
 {
diff --git a/testsuite/systemtap.syscall/kexec_load.c b/testsuite/systemtap.syscall/kexec_load.c
new file mode 100644 (file)
index 0000000..03dc14a
--- /dev/null
@@ -0,0 +1,60 @@
+/* COVERAGE: kexec_load */
+
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <linux/capability.h>
+
+static struct __user_cap_header_struct header;
+static struct __user_cap_data_struct data;
+
+// KEXEC_LOAD(2): The required constants are in the Linux kernel source file
+// linux/kexec.h, which is not currently exported to glibc. Therefore, these
+// constants must be defined manually.
+
+// kexec flags for different usage scenarios
+#define KEXEC_ON_CRASH          0x00000001
+// These values match the ELF architecture values.
+#define KEXEC_ARCH_DEFAULT ( 0 << 16)
+#define KEXEC_ARCH_386     ( 3 << 16)
+
+int main()
+{
+    // Ensure the syscall won't be able to succeed
+    header.version = _LINUX_CAPABILITY_VERSION;
+    header.pid = getpid();
+    capget(&header, &data);
+    data.effective &= ~(1 << CAP_SYS_BOOT);
+    capset(&header, &data);
+
+    // Test normal operation
+    syscall(__NR_kexec_load, NULL, 0, NULL, KEXEC_ON_CRASH|KEXEC_ARCH_386);
+    //staptest// [[[[kexec_load (0x0, 0, 0x0, KEXEC_ON_CRASH|KEXEC_ARCH_386)!!!!ni_syscall ()]]]] = NNNN
+
+    // Limit testing
+    syscall(__NR_kexec_load, (unsigned long)-1, 0, NULL, KEXEC_ARCH_DEFAULT);
+#if __WORDSIZE == 64
+    //staptest// [[[[kexec_load (0xffffffffffffffff, 0, 0x0, KEXEC_ARCH_DEFAULT)!!!!ni_syscall ()]]]] = -NNNN
+#else
+    //staptest// [[[[kexec_load (0xffffffff, 0, 0x0, KEXEC_ARCH_DEFAULT)!!!!ni_syscall ()]]]] = -NNNN
+#endif
+
+    syscall(__NR_kexec_load, NULL, (unsigned long)-1, NULL, KEXEC_ARCH_DEFAULT);
+#if __WORDSIZE == 64
+    //staptest// [[[[kexec_load (0x0, 18446744073709551615, 0x0, KEXEC_ARCH_DEFAULT)!!!!ni_syscall ()]]]] = -NNNN
+#else
+    //staptest// [[[[kexec_load (0x0, 4294967295, 0x0, KEXEC_ARCH_DEFAULT)!!!!ni_syscall ()]]]] = -NNNN
+#endif
+
+    syscall(__NR_kexec_load, NULL, 0, (struct kexec_segment *)-1, KEXEC_ARCH_DEFAULT);
+#ifdef __s390__
+    //staptest// kexec_load (0x0, 0, 0x[7]?[f]+, KEXEC_ARCH_DEFAULT) = -NNNN
+#else
+    //staptest// [[[[kexec_load (0x0, 0, 0x[f]+, KEXEC_ARCH_DEFAULT)!!!!ni_syscall ()]]]] = -NNNN
+#endif
+
+    syscall(__NR_kexec_load, NULL, 0, NULL, (unsigned long)-1);
+    //staptest// [[[[kexec_load (0x0, 0, 0x0, KEXEC_ON_CRASH|[^)]+)!!!!ni_syscall ()]]]] = -NNNN
+
+    return 0;
+}
diff --git a/testsuite/systemtap.syscall/set_tid_address.c b/testsuite/systemtap.syscall/set_tid_address.c
new file mode 100644 (file)
index 0000000..f1a433c
--- /dev/null
@@ -0,0 +1,32 @@
+/* COVERAGE: set_tid_address */
+
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/syscall.h>
+
+int main()
+{
+    int i;
+
+    // set_tid_address() is being called as a part of the testcase
+    // initialization. To ensure that our staptests are correctly
+    // matching code under test, we'll do the limit testing first.
+    // Using syscall() avoids link time issues.
+
+    // Limit testing
+    syscall(__NR_set_tid_address, (int *)-1);
+#ifdef __s390__
+    //staptest// set_tid_address (0x[7]?[f]+) = NNNN
+#else
+    //staptest// set_tid_address (0x[f]+) = NNNN
+#endif
+
+    // Test normal operation
+    syscall(__NR_set_tid_address, &i);
+    //staptest// set_tid_address (XXXX) = NNNN
+
+    syscall(__NR_set_tid_address, NULL);
+    //staptest// set_tid_address (0x0) = NNNN
+
+    return 0;
+}
This page took 0.045775 seconds and 5 git commands to generate.