-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwhythefail.stp
More file actions
68 lines (57 loc) · 2.23 KB
/
whythefail.stp
File metadata and controls
68 lines (57 loc) · 2.23 KB
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
#! /usr/bin/env stap
/* Print a trace of the the last few statements (file:line numbers,
along with selected local variables) that were executed within a
given function, if it ends up returning with a given condition. (No
trace is shown for functions that return with the condition false,
demonstrating use of speculation tapset.)
Usage:
stap whythefail.stp PROC_OR_KERNEL FUNCTION_NAME CONDITION_EXPRESSION [$VARIABLE$]
PROC_OR_KERNEL: the first part of the probe point, e.g.:
'kernel' 'module("foo")' or 'process("bar")'
FUNCTION_NAME: the function name (assumed non-recursive)
CONDITION: expression to evaluate at function return, e.g.:
'$return != 0' or '1' or 'randint(100)<20'
VARIABLE: optional context-variable string to print at each statement, e.g.:
'$a_var$' or '@var("global")$' or (default) '$$vars'
If the script is invoked with -c CMD or -x PID, probes are filtered
for that process target-set (it and its descendants).
e.g.:
stap whythefail.stp kernel do_mlock '$return < 0'
*/
global specs%
global counts
probe $1 . function(@2) . call {
if (target() && !target_set_pid(pid())) next;
specs[tid()] = speculation()
counts["entry"] <<< 1
}
probe $1 . statement(@2 "@*:*") {
if (target() && !target_set_pid(pid())) next;
tokenize(pp(),"@");
fileline=tokenize("","@");
file=tokenize(fileline,":\"");
line=tokenize("",":\"");
speculate(specs[tid()], sprintf("%s[%d] %s:%s %s\n",
execname(), tid(), file, line,
%( $# >= 4
%? @4.": ".@choose_defined($4,"?")
%: "$$vars: ".$$vars %) ))
counts["statement"] <<< 1
}
probe $1 . function(@2) . return {
if (target() && !target_set_pid(pid())) next;
if ($3) {
printf("\n%s[%d] %s function(%s) $return: %s\n", execname(), tid(), @1, @2, $return$)
commit(specs[tid()])
counts["exit-hit"] <<< 1
} else {
discard(specs[tid()])
counts["exit-miss"] <<< 1
}
}
probe end,error {
printf("\nstatistics:\n")
foreach (reason+ in counts) {
printf("%s count: %d\n", reason, @count(counts[reason]))
}
}