summaryrefslogtreecommitdiffstats
path: root/testsuite/systemtap.stress/current.stp
blob: 0b2a7f949090493ba310e6ce3754fc971a64de64 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/*
 * current.stp  (requires Guru mode)
 *
 * Test the validity of the current pointer in various contexts.
 */

global length

function commlen:long () %{
    THIS->__retvalue = strlen(current->comm);
%}

function pcommlen:long () %{
    THIS->__retvalue = strlen(current->parent->comm);
%}

probe begin { println("systemtap starting probe") }

probe
    timer.profile,
    %( arch != "ia64" %?
      # __switch_to is macro definition in ia64,
      # and ia64_switch_to is defined in assemble language
      %( arch != "x86_64" %?
        # __switch_to can not be probed on x86_64 - see PR2068
        kernel.function("__switch_to").call,
        %( arch != "i386" %?
          # __switch_to.return is broken on i686 - see PR4542
          kernel.function("__switch_to").return,
        %)
      %)
    %)

    /* XXX
     * It would be nice if we could just do this:
     *    kernel.statement("__switch_to@*:*")
     * to probe every line in the function
     */

    /* add other kernels/archs here as desired... */
    %( arch == "x86_64" %?
       %( kernel_vr == "2.6.9-22.ELsmp" %?
          /* the lines before, at, and after the update of pcurrent */
          kernel.statement("__switch_to@arch/x86_64/kernel/process.c:508"),
          kernel.statement("__switch_to@arch/x86_64/kernel/process.c:509"),
          kernel.statement("__switch_to@arch/x86_64/kernel/process.c:510"),
       %)
       %( kernel_vr == "2.6.9-24.ELsmp" %?
          /* the lines before, at, and after the update of pcurrent */
          kernel.statement("__switch_to@arch/x86_64/kernel/process.c:501"),
          kernel.statement("__switch_to@arch/x86_64/kernel/process.c:502"),
          kernel.statement("__switch_to@arch/x86_64/kernel/process.c:503"),
       %)
    %)

    kernel.function("*@kernel/sched.c").call,
    kernel.function("*@kernel/sched.c").return,
    module("*").function("*interrupt*").call ?,
    module("*").function("*interrupt*").return ?
{
    length <<< commlen()
    length <<< pcommlen()
}

function get_TASK_COMM_LEN:long() %{
    /* TASK_COMM_LEN was introduced in 2.6.11, before which
     * the length of the comm string was hard-coded to 16 */
#ifdef TASK_COMM_LEN
    THIS->__retvalue = TASK_COMM_LEN;
#else
    THIS->__retvalue = 16;
#endif
%}

probe end {
    println("systemtap ending probe")
    printf("count = %d\n", @count(length))
    printf("sum = %d\n", @sum(length))
    printf("min = %d\n", @min(length))
    printf("max = %d\n", @max(length))
    printf("avg = %d\n", @avg(length))

    /*
     * Check that the min & max lengths look reasonable.  If any string was
     * either empty or too big, then the current pointer probably wasn't
     * valid, even though it dereferenced without crashing.
     */
    if (@min(length) > 0) {
        println("systemtap test success")
    } else {
        println("unexpected minimum length")
        println("systemtap test failure")
    }
    if (@max(length) < get_TASK_COMM_LEN()) {
        println("systemtap test success")
    } else {
        println("unexpected maximum length")
        println("systemtap test failure")
    }
}