-
Notifications
You must be signed in to change notification settings - Fork 7
/
etrace
executable file
·148 lines (128 loc) · 3.2 KB
/
etrace
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/bin/bash
# Run syscalls tracing of a given command
# Usage:
# etrace COMMAND ...
print_usage () {
echo "Usage: etrace [-hlimte] [-w WORK_DIR] [--] COMMAND ..."
}
echo_err () {
echo "[!] $1"
}
if [ "$#" -lt 1 ]; then
print_usage
exit 1
fi
# -------- parse args
SAVE_KERNEL_LOG=
WORK_DIR=$(pwd)
INITCWD=$(pwd)
MODULE_PARAMS=""
while getopts "hilmtew:" opt; do
case "$opt" in
h)
print_usage
exit 0
;;
l)
SAVE_KERNEL_LOG=y
;;
w)
WORK_DIR="$OPTARG"
mkdir -p "$WORK_DIR"
;;
i)
MODULE_PARAMS="$MODULE_PARAMS ignore_repeated_opens=1"
;;
t)
MODULE_PARAMS="$MODULE_PARAMS trace_thread_names=1"
;;
m)
MODULE_PARAMS="$MODULE_PARAMS enable_mount=1"
;;
e)
MODULE_PARAMS="$MODULE_PARAMS trace_env_vars=1"
;;
esac
done
# Remove script's arguments so that "$@" contains the command to run
# under tracer
shift $((OPTIND-1))
# If arguments were separated from the command by "--", remove it too
[ "${1:-}" = "--" ] && shift
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
NPROC=$(nproc)
NPROC=$(expr $NPROC - 1)
# -------- setting up ftrace
if (( $EUID != 0 )); then
sudo -n setup_etrace.sh -f
else
setup_etrace.sh -f
fi
if [ "$?" -ne 0 ]; then
echo_err "setup_etrace.sh -f failed"
exit 1
fi
# -------- save our CWD
echo "INITCWD=$INITCWD" > "$WORK_DIR/.nfsdb"
# -------- set up event listener
#${DIR}/etrace_cat "/sys/kernel/debug/tracing/trace_pipe" > "$WORK_DIR/.nfsdb" &
${DIR}/cati "/sys/kernel/debug/tracing/trace_pipe" >> "$WORK_DIR/.nfsdb" &
LISTENER_PID="$!"
if (( $EUID != 0 )); then
sudo -n renice -n -18 -p $LISTENER_PID >/dev/null 2>&1
else
renice -n -18 -p $LISTENER_PID >/dev/null 2>&1
fi
# -------- save kernel log
if [ "$SAVE_KERNEL_LOG" = "y" ]; then
dmesg -w > "$WORK_DIR/.nfsdb.klog" &
KLOGGER_PID="$!"
fi
# -------- install bas_tracer module
MYPID="$$"
if (( $EUID != 0 )); then
sudo -n setup_etrace.sh -i $MYPID $MODULE_PARAMS
else
setup_etrace.sh -i $MYPID $MODULE_PARAMS
fi
if [ "$?" -ne 0 ]; then
echo_err "setup_etrace.sh -i failed"
exit 1
fi
# -------- run the command
"$@"
RV="$?"
# -------- remove bas_tracer module
if (( $EUID != 0 )); then
sudo -n setup_etrace.sh -r
else
setup_etrace.sh -r
fi
if [ "$?" -ne 0 ]; then
echo_err "setup_etrace.sh -r failed"
exit 1
fi
# Save stat information to see if any events have been missing
rm -f "$WORK_DIR/.nfsdb.stats" && touch "$WORK_DIR/.nfsdb.stats"
for i in `seq 0 $NPROC`; do
echo "##---------- CPU $i ---------- ##" >> "$WORK_DIR/.nfsdb.stats"
cat "/sys/kernel/debug/tracing/per_cpu/cpu$i/stats" >> "$WORK_DIR/.nfsdb.stats"
done
# -------- stop event listener
if [ -f "${WORK_DIR}/.nfsdb" ]; then
PREV_LINE=`tail -n 1 ${WORK_DIR}/.nfsdb`
sleep 2
CURR_LINE=`tail -n 1 ${WORK_DIR}/.nfsdb`
while [ "${PREV_LINE}" != "${CURR_LINE}" ]; do
PREV_LINE=${CURR_LINE}
sleep 2
CURR_LINE=`tail -n 1 ${WORK_DIR}/.nfsdb`
done
fi
kill -SIGINT "${LISTENER_PID}"
# -------- stop kernel logger
if [ "$SAVE_KERNEL_LOG" = "y" ]; then
kill -SIGINT "${KLOGGER_PID}"
fi
# We're done here
exit $RV