Commit 218f7482 authored by William Cohen's avatar William Cohen Committed by yonghong-song

Wcohen/efficiency (#2063)

* Reduce instrumentation overhead with the sys_enter and sys_exit tracepoints

The ucalls script initially used kprobes and kretprobes on each of the
hundreds of syscalls functions in the system.  This approach causes a
large number of probes to be set up at the start and removed at the
conclusion of the script's execution resulting in slow start up.

Like the syscount.py script the ucall syscall instrumentation has been
modified to use the sys_enter and sys_exit tracepoints.  This only
requires the installation and removal of one or two tracepoints to
implement and results in much shorter times to start and stop the
ucalls script.

Another benefit of this change is syscalls on newer kernels will be
monitored with the "-S" option.  The regular expression used to find
the locations for the kprobes and kretprobes for all the possible
syscall functions would not would match the syscall function naming
convention in newer kernels.

* Update ucalls_examples.txt to match current "-S" option output

* Add required "import subprocess" and remove unneeded "global syscalls"

* Factor out the syscall_name code into a separate python module syscall.py

Multiple scripts are going to find the syscall_name() function useful
when using the syscall tracepoints.  Factoring out this code into a
separate python module avoids having to replicate this code in
multiple scripts.

* Use the syscall_name() function in syscount.py to make it more compact.

* Update the default syscall mappings and the way that they were generated

The default table was missing some newer syscall mapping. Regenerated
the table using the syscallent.h file from Fedora 30
strace-4.25-1.fc30.src.rpm.  Also updated the comment with the command
actually used to generate the mappings.

* Add license information and upsdate the syscalls

The default x86_64 syscall dictionary mapping syscalls numbers to
names has been updated. The following syscall x86_64 names have been
updated:

    18: b"pwrite64",
    60: b"exit",
    166: b"umount2",

The following syscall x86_64 have been added:

    313: b"finit_module",
    314: b"sched_setattr",
    315: b"sched_getattr",
    316: b"renameat2",
    317: b"seccomp",
    318: b"getrandom",
    319: b"memfd_create",
    320: b"kexec_file_load",
    321: b"bpf",
    322: b"execveat",
    323: b"userfaultfd",
    324: b"membarrier",
    325: b"mlock2",
    326: b"copy_file_range",
    327: b"preadv2",
    328: b"pwritev2",
    329: b"pkey_mprotect",
    330: b"pkey_alloc",
    331: b"pkey_free",
    332: b"statx",
    333: b"io_pgetevents",
    334: b"rseq",

* Eliminate stderr output and use of shell features

Redirect all stderr output so it isn't seen.  Also avoid use of the
shell pipe and tail command.  Just strip off the first line in the
python code instead.

* Update lib/ucalls.py smoke test to required linux-4.7

The use of tracepoints in the ucalls.py requires linux-4.7. Changed
the test to only run with a suitable kernel.  The libs/ucalls.py
script is no longer inserting hundreds of kprobes and is much faster
as a result, so removed the timeout adjustment and the comment about
it being slow.
parent f3fd8e30
# Copyright (c) PLUMgrid, Inc. # Copyright (c) PLUMgrid, Inc.
# Licensed under the Apache License, Version 2.0 (the "License") # Licensed under the Apache License, Version 2.0 (the "License")
set(PYTHON_SRC __init__.py perf.py tcp.py utils.py libbcc.py table.py usdt.py) set(PYTHON_SRC __init__.py perf.py tcp.py utils.py libbcc.py syscall.py table.py usdt.py)
foreach (PY_SRC ${PYTHON_SRC}) foreach (PY_SRC ${PYTHON_SRC})
configure_file(bcc/${PY_SRC} ${CMAKE_CURRENT_BINARY_DIR}/bcc/${PY_SRC} COPYONLY) configure_file(bcc/${PY_SRC} ${CMAKE_CURRENT_BINARY_DIR}/bcc/${PY_SRC} COPYONLY)
......
...@@ -27,6 +27,7 @@ basestring = (unicode if sys.version_info[0] < 3 else str) ...@@ -27,6 +27,7 @@ basestring = (unicode if sys.version_info[0] < 3 else str)
from .libbcc import lib, bcc_symbol, bcc_symbol_option, _SYM_CB_TYPE from .libbcc import lib, bcc_symbol, bcc_symbol_option, _SYM_CB_TYPE
from .table import Table, PerfEventArray from .table import Table, PerfEventArray
from .perf import Perf from .perf import Perf
from .syscall import syscall_name
from .utils import get_online_cpus, printb, _assert_is_bytes, ArgString from .utils import get_online_cpus, printb, _assert_is_bytes, ArgString
from .version import __version__ from .version import __version__
......
# Copyright 2017 Sasha Goldshtein
# Copyright 2018 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""syscall.py contains functions useful for mapping between syscall names and numbers"""
import subprocess
import platform
#
# Syscall table for Linux x86_64, not very recent.
# Automatically generated from strace/linux/x86_64/syscallent.h using the
# following command:
#
# cat syscallent.h | awk -F, '{ gsub(/[ \t"}]/, "", $4);
# gsub(/[\[\] \t{]/, "", $1); split($1, a, "=");
# print " "a[1]": b\""$4"\","; }
# BEGIN { print "syscalls = {" }
# END { print "}" '}
syscalls = {
0: b"read",
1: b"write",
2: b"open",
3: b"close",
4: b"stat",
5: b"fstat",
6: b"lstat",
7: b"poll",
8: b"lseek",
9: b"mmap",
10: b"mprotect",
11: b"munmap",
12: b"brk",
13: b"rt_sigaction",
14: b"rt_sigprocmask",
15: b"rt_sigreturn",
16: b"ioctl",
17: b"pread64",
18: b"pwrite64",
19: b"readv",
20: b"writev",
21: b"access",
22: b"pipe",
23: b"select",
24: b"sched_yield",
25: b"mremap",
26: b"msync",
27: b"mincore",
28: b"madvise",
29: b"shmget",
30: b"shmat",
31: b"shmctl",
32: b"dup",
33: b"dup2",
34: b"pause",
35: b"nanosleep",
36: b"getitimer",
37: b"alarm",
38: b"setitimer",
39: b"getpid",
40: b"sendfile",
41: b"socket",
42: b"connect",
43: b"accept",
44: b"sendto",
45: b"recvfrom",
46: b"sendmsg",
47: b"recvmsg",
48: b"shutdown",
49: b"bind",
50: b"listen",
51: b"getsockname",
52: b"getpeername",
53: b"socketpair",
54: b"setsockopt",
55: b"getsockopt",
56: b"clone",
57: b"fork",
58: b"vfork",
59: b"execve",
60: b"exit",
61: b"wait4",
62: b"kill",
63: b"uname",
64: b"semget",
65: b"semop",
66: b"semctl",
67: b"shmdt",
68: b"msgget",
69: b"msgsnd",
70: b"msgrcv",
71: b"msgctl",
72: b"fcntl",
73: b"flock",
74: b"fsync",
75: b"fdatasync",
76: b"truncate",
77: b"ftruncate",
78: b"getdents",
79: b"getcwd",
80: b"chdir",
81: b"fchdir",
82: b"rename",
83: b"mkdir",
84: b"rmdir",
85: b"creat",
86: b"link",
87: b"unlink",
88: b"symlink",
89: b"readlink",
90: b"chmod",
91: b"fchmod",
92: b"chown",
93: b"fchown",
94: b"lchown",
95: b"umask",
96: b"gettimeofday",
97: b"getrlimit",
98: b"getrusage",
99: b"sysinfo",
100: b"times",
101: b"ptrace",
102: b"getuid",
103: b"syslog",
104: b"getgid",
105: b"setuid",
106: b"setgid",
107: b"geteuid",
108: b"getegid",
109: b"setpgid",
110: b"getppid",
111: b"getpgrp",
112: b"setsid",
113: b"setreuid",
114: b"setregid",
115: b"getgroups",
116: b"setgroups",
117: b"setresuid",
118: b"getresuid",
119: b"setresgid",
120: b"getresgid",
121: b"getpgid",
122: b"setfsuid",
123: b"setfsgid",
124: b"getsid",
125: b"capget",
126: b"capset",
127: b"rt_sigpending",
128: b"rt_sigtimedwait",
129: b"rt_sigqueueinfo",
130: b"rt_sigsuspend",
131: b"sigaltstack",
132: b"utime",
133: b"mknod",
134: b"uselib",
135: b"personality",
136: b"ustat",
137: b"statfs",
138: b"fstatfs",
139: b"sysfs",
140: b"getpriority",
141: b"setpriority",
142: b"sched_setparam",
143: b"sched_getparam",
144: b"sched_setscheduler",
145: b"sched_getscheduler",
146: b"sched_get_priority_max",
147: b"sched_get_priority_min",
148: b"sched_rr_get_interval",
149: b"mlock",
150: b"munlock",
151: b"mlockall",
152: b"munlockall",
153: b"vhangup",
154: b"modify_ldt",
155: b"pivot_root",
156: b"_sysctl",
157: b"prctl",
158: b"arch_prctl",
159: b"adjtimex",
160: b"setrlimit",
161: b"chroot",
162: b"sync",
163: b"acct",
164: b"settimeofday",
165: b"mount",
166: b"umount2",
167: b"swapon",
168: b"swapoff",
169: b"reboot",
170: b"sethostname",
171: b"setdomainname",
172: b"iopl",
173: b"ioperm",
174: b"create_module",
175: b"init_module",
176: b"delete_module",
177: b"get_kernel_syms",
178: b"query_module",
179: b"quotactl",
180: b"nfsservctl",
181: b"getpmsg",
182: b"putpmsg",
183: b"afs_syscall",
184: b"tuxcall",
185: b"security",
186: b"gettid",
187: b"readahead",
188: b"setxattr",
189: b"lsetxattr",
190: b"fsetxattr",
191: b"getxattr",
192: b"lgetxattr",
193: b"fgetxattr",
194: b"listxattr",
195: b"llistxattr",
196: b"flistxattr",
197: b"removexattr",
198: b"lremovexattr",
199: b"fremovexattr",
200: b"tkill",
201: b"time",
202: b"futex",
203: b"sched_setaffinity",
204: b"sched_getaffinity",
205: b"set_thread_area",
206: b"io_setup",
207: b"io_destroy",
208: b"io_getevents",
209: b"io_submit",
210: b"io_cancel",
211: b"get_thread_area",
212: b"lookup_dcookie",
213: b"epoll_create",
214: b"epoll_ctl_old",
215: b"epoll_wait_old",
216: b"remap_file_pages",
217: b"getdents64",
218: b"set_tid_address",
219: b"restart_syscall",
220: b"semtimedop",
221: b"fadvise64",
222: b"timer_create",
223: b"timer_settime",
224: b"timer_gettime",
225: b"timer_getoverrun",
226: b"timer_delete",
227: b"clock_settime",
228: b"clock_gettime",
229: b"clock_getres",
230: b"clock_nanosleep",
231: b"exit_group",
232: b"epoll_wait",
233: b"epoll_ctl",
234: b"tgkill",
235: b"utimes",
236: b"vserver",
237: b"mbind",
238: b"set_mempolicy",
239: b"get_mempolicy",
240: b"mq_open",
241: b"mq_unlink",
242: b"mq_timedsend",
243: b"mq_timedreceive",
244: b"mq_notify",
245: b"mq_getsetattr",
246: b"kexec_load",
247: b"waitid",
248: b"add_key",
249: b"request_key",
250: b"keyctl",
251: b"ioprio_set",
252: b"ioprio_get",
253: b"inotify_init",
254: b"inotify_add_watch",
255: b"inotify_rm_watch",
256: b"migrate_pages",
257: b"openat",
258: b"mkdirat",
259: b"mknodat",
260: b"fchownat",
261: b"futimesat",
262: b"newfstatat",
263: b"unlinkat",
264: b"renameat",
265: b"linkat",
266: b"symlinkat",
267: b"readlinkat",
268: b"fchmodat",
269: b"faccessat",
270: b"pselect6",
271: b"ppoll",
272: b"unshare",
273: b"set_robust_list",
274: b"get_robust_list",
275: b"splice",
276: b"tee",
277: b"sync_file_range",
278: b"vmsplice",
279: b"move_pages",
280: b"utimensat",
281: b"epoll_pwait",
282: b"signalfd",
283: b"timerfd_create",
284: b"eventfd",
285: b"fallocate",
286: b"timerfd_settime",
287: b"timerfd_gettime",
288: b"accept4",
289: b"signalfd4",
290: b"eventfd2",
291: b"epoll_create1",
292: b"dup3",
293: b"pipe2",
294: b"inotify_init1",
295: b"preadv",
296: b"pwritev",
297: b"rt_tgsigqueueinfo",
298: b"perf_event_open",
299: b"recvmmsg",
300: b"fanotify_init",
301: b"fanotify_mark",
302: b"prlimit64",
303: b"name_to_handle_at",
304: b"open_by_handle_at",
305: b"clock_adjtime",
306: b"syncfs",
307: b"sendmmsg",
308: b"setns",
309: b"getcpu",
310: b"process_vm_readv",
311: b"process_vm_writev",
312: b"kcmp",
313: b"finit_module",
314: b"sched_setattr",
315: b"sched_getattr",
316: b"renameat2",
317: b"seccomp",
318: b"getrandom",
319: b"memfd_create",
320: b"kexec_file_load",
321: b"bpf",
322: b"execveat",
323: b"userfaultfd",
324: b"membarrier",
325: b"mlock2",
326: b"copy_file_range",
327: b"preadv2",
328: b"pwritev2",
329: b"pkey_mprotect",
330: b"pkey_alloc",
331: b"pkey_free",
332: b"statx",
333: b"io_pgetevents",
334: b"rseq",
}
# Try to use ausyscall if it is available, because it can give us an up-to-date
# list of syscalls for various architectures, rather than the x86-64 hardcoded
# list above.
def _parse_syscall(line):
parts = line.split()
return (int(parts[0]), parts[1].strip())
try:
# Skip the first line, which is a header. The rest of the lines are simply
# SYSCALL_NUM\tSYSCALL_NAME pairs.
out = subprocess.check_output('ausyscall --dump', stderr=subprocess.STDOUT)
# remove the first line of expected output
out = out.split('\n',1)[1]
syscalls = dict(map(_parse_syscall, out.strip().split(b'\n')))
except Exception as e:
if platform.machine() == "x86_64":
pass
else:
raise Exception("ausyscall: command not found")
def syscall_name(syscall_num):
"""Return the syscall name for the particular syscall number."""
return syscalls.get(syscall_num, b"[unknown: %d]" % syscall_num)
...@@ -340,12 +340,9 @@ class SmokeTests(TestCase): ...@@ -340,12 +340,9 @@ class SmokeTests(TestCase):
def test_ttysnoop(self): def test_ttysnoop(self):
self.run_with_int("ttysnoop.py /dev/console") self.run_with_int("ttysnoop.py /dev/console")
@skipUnless(kernel_version_ge(4,4), "requires kernel >= 4.4") @skipUnless(kernel_version_ge(4,7), "requires kernel >= 4.7")
def test_ucalls(self): def test_ucalls(self):
# This attaches a large number (300+) kprobes, which can be slow, self.run_with_int("lib/ucalls.py -l none -S %d" % os.getpid())
# so use an increased timeout value.
self.run_with_int("lib/ucalls.py -l none -S %d" % os.getpid(),
timeout=60, kill_timeout=60)
@skipUnless(kernel_version_ge(4,4), "requires kernel >= 4.4") @skipUnless(kernel_version_ge(4,4), "requires kernel >= 4.4")
def test_uflow(self): def test_uflow(self):
......
...@@ -14,9 +14,8 @@ ...@@ -14,9 +14,8 @@
from __future__ import print_function from __future__ import print_function
import argparse import argparse
from bcc import BPF, USDT, utils
from time import sleep from time import sleep
import os from bcc import BPF, USDT, utils, syscall_name
languages = ["java", "perl", "php", "python", "ruby", "tcl"] languages = ["java", "perl", "php", "python", "ruby", "tcl"]
...@@ -130,7 +129,7 @@ struct info_t { ...@@ -130,7 +129,7 @@ struct info_t {
}; };
struct syscall_entry_t { struct syscall_entry_t {
u64 timestamp; u64 timestamp;
u64 ip; u64 id;
}; };
#ifndef LATENCY #ifndef LATENCY
...@@ -198,37 +197,35 @@ int trace_return(struct pt_regs *ctx) { ...@@ -198,37 +197,35 @@ int trace_return(struct pt_regs *ctx) {
#endif // NOLANG #endif // NOLANG
#ifdef SYSCALLS #ifdef SYSCALLS
int syscall_entry(struct pt_regs *ctx) { TRACEPOINT_PROBE(raw_syscalls, sys_enter) {
u64 pid = bpf_get_current_pid_tgid(); u64 pid = bpf_get_current_pid_tgid();
u64 *valp, ip = PT_REGS_IP(ctx), val = 0; u64 *valp, id = args->id, val = 0;
PID_FILTER PID_FILTER
#ifdef LATENCY #ifdef LATENCY
struct syscall_entry_t data = {}; struct syscall_entry_t data = {};
data.timestamp = bpf_ktime_get_ns(); data.timestamp = bpf_ktime_get_ns();
data.ip = ip; data.id = id;
sysentry.update(&pid, &data);
#endif #endif
#ifndef LATENCY #ifndef LATENCY
valp = syscounts.lookup_or_init(&ip, &val); valp = syscounts.lookup_or_init(&id, &val);
++(*valp); ++(*valp);
#endif
#ifdef LATENCY
sysentry.update(&pid, &data);
#endif #endif
return 0; return 0;
} }
#ifdef LATENCY #ifdef LATENCY
int syscall_return(struct pt_regs *ctx) { TRACEPOINT_PROBE(raw_syscalls, sys_exit) {
struct syscall_entry_t *e; struct syscall_entry_t *e;
struct info_t *info, zero = {}; struct info_t *info, zero = {};
u64 pid = bpf_get_current_pid_tgid(), ip; u64 pid = bpf_get_current_pid_tgid(), id;
PID_FILTER PID_FILTER
e = sysentry.lookup(&pid); e = sysentry.lookup(&pid);
if (!e) { if (!e) {
return 0; // missed the entry event return 0; // missed the entry event
} }
ip = e->ip; id = e->id;
info = systimes.lookup_or_init(&ip, &zero); info = systimes.lookup_or_init(&id, &zero);
info->num_calls += 1; info->num_calls += 1;
info->total_ns += bpf_ktime_get_ns() - e->timestamp; info->total_ns += bpf_ktime_get_ns() - e->timestamp;
sysentry.delete(&pid); sysentry.delete(&pid);
...@@ -260,12 +257,7 @@ if args.ebpf or args.verbose: ...@@ -260,12 +257,7 @@ if args.ebpf or args.verbose:
bpf = BPF(text=program, usdt_contexts=[usdt] if usdt else []) bpf = BPF(text=program, usdt_contexts=[usdt] if usdt else [])
if args.syscalls: if args.syscalls:
syscall_regex = "^[Ss]y[Ss]_.*" print("Attached kernel tracepoints for syscall tracing.")
bpf.attach_kprobe(event_re=syscall_regex, fn_name="syscall_entry")
if args.latency:
bpf.attach_kretprobe(event_re=syscall_regex, fn_name="syscall_return")
print("Attached %d kernel probes for syscall tracing." %
bpf.num_open_kprobes())
def get_data(): def get_data():
# Will be empty when no language was specified for tracing # Will be empty when no language was specified for tracing
...@@ -284,12 +276,12 @@ def get_data(): ...@@ -284,12 +276,12 @@ def get_data():
if args.syscalls: if args.syscalls:
if args.latency: if args.latency:
syscalls = map(lambda kv: (bpf.ksym(kv[0].value), syscalls = map(lambda kv: (syscall_name(kv[0].value).decode('utf-8', 'replace'),
(kv[1].num_calls, kv[1].total_ns)), (kv[1].num_calls, kv[1].total_ns)),
bpf["systimes"].items()) bpf["systimes"].items())
data.extend(syscalls) data.extend(syscalls)
else: else:
syscalls = map(lambda kv: (bpf.ksym(kv[0].value), syscalls = map(lambda kv: (syscall_name(kv[0].value).decode('utf-8', 'replace'),
(kv[1].value, 0)), (kv[1].value, 0)),
bpf["syscounts"].items()) bpf["syscounts"].items())
data.extend(syscalls) data.extend(syscalls)
......
...@@ -27,22 +27,21 @@ slowy/App.isPrime 8969 4841017.64 ...@@ -27,22 +27,21 @@ slowy/App.isPrime 8969 4841017.64
To trace only syscalls in a particular process and print the top 10 most To trace only syscalls in a particular process and print the top 10 most
frequently-invoked ones: frequently-invoked ones:
# ucalls -ST 10 3018 # ucalls -l none -ST 10 7913
Attached 375 kernel probes for syscall tracing. Attached kernel tracepoints for syscall tracing.
Tracing calls in process 3018 (language: none)... Ctrl-C to quit. Tracing calls in process 7913 (language: none)... Ctrl-C to quit.
METHOD # CALLS
sys_rt_sigaction 4
SyS_rt_sigprocmask 4
sys_mprotect 5
sys_read 22
SyS_write 39
SyS_epoll_wait 42
sys_futex 177
SyS_mmap 180
sys_mmap_pgoff 181
sys_munmap 817
^C ^C
METHOD # CALLS
timerfd_settime 9
tgkill 10
getpid 10
stat 80
writev 158
pselect6 204
rt_sigreturn 301
rt_sigprocmask 872
poll 1387
recvmsg 1417
Detaching kernel probes, please wait... Detaching kernel probes, please wait...
......
...@@ -9,368 +9,21 @@ ...@@ -9,368 +9,21 @@
# #
# 15-Feb-2017 Sasha Goldshtein Created this. # 15-Feb-2017 Sasha Goldshtein Created this.
from bcc import BPF
from bcc.utils import printb
from time import sleep, strftime from time import sleep, strftime
import argparse import argparse
import errno import errno
import itertools import itertools
import subprocess
import sys import sys
import signal import signal
import platform from bcc import BPF
from bcc.utils import printb
from bcc.syscall import syscall_name
if sys.version_info.major < 3: if sys.version_info.major < 3:
izip_longest = itertools.izip_longest izip_longest = itertools.izip_longest
else: else:
izip_longest = itertools.zip_longest izip_longest = itertools.zip_longest
#
# Syscall table for Linux x86_64, not very recent.
# Automatically generated from strace/linux/x86_64/syscallent.h using the
# following command:
#
# cat syscallent.h | awk -F, '{ gsub(/[ \t"}]/, "", $4);
# gsub(/[ \t/*]/, "", $5);
# print " "$5": \""$4"\","; }
# BEGIN { print "syscalls = {" }
# END { print "}" }'
#
syscalls = {
0: b"read",
1: b"write",
2: b"open",
3: b"close",
4: b"stat",
5: b"fstat",
6: b"lstat",
7: b"poll",
8: b"lseek",
9: b"mmap",
10: b"mprotect",
11: b"munmap",
12: b"brk",
13: b"rt_sigaction",
14: b"rt_sigprocmask",
15: b"rt_sigreturn",
16: b"ioctl",
17: b"pread",
18: b"pwrite",
19: b"readv",
20: b"writev",
21: b"access",
22: b"pipe",
23: b"select",
24: b"sched_yield",
25: b"mremap",
26: b"msync",
27: b"mincore",
28: b"madvise",
29: b"shmget",
30: b"shmat",
31: b"shmctl",
32: b"dup",
33: b"dup2",
34: b"pause",
35: b"nanosleep",
36: b"getitimer",
37: b"alarm",
38: b"setitimer",
39: b"getpid",
40: b"sendfile",
41: b"socket",
42: b"connect",
43: b"accept",
44: b"sendto",
45: b"recvfrom",
46: b"sendmsg",
47: b"recvmsg",
48: b"shutdown",
49: b"bind",
50: b"listen",
51: b"getsockname",
52: b"getpeername",
53: b"socketpair",
54: b"setsockopt",
55: b"getsockopt",
56: b"clone",
57: b"fork",
58: b"vfork",
59: b"execve",
60: b"_exit",
61: b"wait4",
62: b"kill",
63: b"uname",
64: b"semget",
65: b"semop",
66: b"semctl",
67: b"shmdt",
68: b"msgget",
69: b"msgsnd",
70: b"msgrcv",
71: b"msgctl",
72: b"fcntl",
73: b"flock",
74: b"fsync",
75: b"fdatasync",
76: b"truncate",
77: b"ftruncate",
78: b"getdents",
79: b"getcwd",
80: b"chdir",
81: b"fchdir",
82: b"rename",
83: b"mkdir",
84: b"rmdir",
85: b"creat",
86: b"link",
87: b"unlink",
88: b"symlink",
89: b"readlink",
90: b"chmod",
91: b"fchmod",
92: b"chown",
93: b"fchown",
94: b"lchown",
95: b"umask",
96: b"gettimeofday",
97: b"getrlimit",
98: b"getrusage",
99: b"sysinfo",
100: b"times",
101: b"ptrace",
102: b"getuid",
103: b"syslog",
104: b"getgid",
105: b"setuid",
106: b"setgid",
107: b"geteuid",
108: b"getegid",
109: b"setpgid",
110: b"getppid",
111: b"getpgrp",
112: b"setsid",
113: b"setreuid",
114: b"setregid",
115: b"getgroups",
116: b"setgroups",
117: b"setresuid",
118: b"getresuid",
119: b"setresgid",
120: b"getresgid",
121: b"getpgid",
122: b"setfsuid",
123: b"setfsgid",
124: b"getsid",
125: b"capget",
126: b"capset",
127: b"rt_sigpending",
128: b"rt_sigtimedwait",
129: b"rt_sigqueueinfo",
130: b"rt_sigsuspend",
131: b"sigaltstack",
132: b"utime",
133: b"mknod",
134: b"uselib",
135: b"personality",
136: b"ustat",
137: b"statfs",
138: b"fstatfs",
139: b"sysfs",
140: b"getpriority",
141: b"setpriority",
142: b"sched_setparam",
143: b"sched_getparam",
144: b"sched_setscheduler",
145: b"sched_getscheduler",
146: b"sched_get_priority_max",
147: b"sched_get_priority_min",
148: b"sched_rr_get_interval",
149: b"mlock",
150: b"munlock",
151: b"mlockall",
152: b"munlockall",
153: b"vhangup",
154: b"modify_ldt",
155: b"pivot_root",
156: b"_sysctl",
157: b"prctl",
158: b"arch_prctl",
159: b"adjtimex",
160: b"setrlimit",
161: b"chroot",
162: b"sync",
163: b"acct",
164: b"settimeofday",
165: b"mount",
166: b"umount",
167: b"swapon",
168: b"swapoff",
169: b"reboot",
170: b"sethostname",
171: b"setdomainname",
172: b"iopl",
173: b"ioperm",
174: b"create_module",
175: b"init_module",
176: b"delete_module",
177: b"get_kernel_syms",
178: b"query_module",
179: b"quotactl",
180: b"nfsservctl",
181: b"getpmsg",
182: b"putpmsg",
183: b"afs_syscall",
184: b"tuxcall",
185: b"security",
186: b"gettid",
187: b"readahead",
188: b"setxattr",
189: b"lsetxattr",
190: b"fsetxattr",
191: b"getxattr",
192: b"lgetxattr",
193: b"fgetxattr",
194: b"listxattr",
195: b"llistxattr",
196: b"flistxattr",
197: b"removexattr",
198: b"lremovexattr",
199: b"fremovexattr",
200: b"tkill",
201: b"time",
202: b"futex",
203: b"sched_setaffinity",
204: b"sched_getaffinity",
205: b"set_thread_area",
206: b"io_setup",
207: b"io_destroy",
208: b"io_getevents",
209: b"io_submit",
210: b"io_cancel",
211: b"get_thread_area",
212: b"lookup_dcookie",
213: b"epoll_create",
214: b"epoll_ctl_old",
215: b"epoll_wait_old",
216: b"remap_file_pages",
217: b"getdents64",
218: b"set_tid_address",
219: b"restart_syscall",
220: b"semtimedop",
221: b"fadvise64",
222: b"timer_create",
223: b"timer_settime",
224: b"timer_gettime",
225: b"timer_getoverrun",
226: b"timer_delete",
227: b"clock_settime",
228: b"clock_gettime",
229: b"clock_getres",
230: b"clock_nanosleep",
231: b"exit_group",
232: b"epoll_wait",
233: b"epoll_ctl",
234: b"tgkill",
235: b"utimes",
236: b"vserver",
237: b"mbind",
238: b"set_mempolicy",
239: b"get_mempolicy",
240: b"mq_open",
241: b"mq_unlink",
242: b"mq_timedsend",
243: b"mq_timedreceive",
244: b"mq_notify",
245: b"mq_getsetattr",
246: b"kexec_load",
247: b"waitid",
248: b"add_key",
249: b"request_key",
250: b"keyctl",
251: b"ioprio_set",
252: b"ioprio_get",
253: b"inotify_init",
254: b"inotify_add_watch",
255: b"inotify_rm_watch",
256: b"migrate_pages",
257: b"openat",
258: b"mkdirat",
259: b"mknodat",
260: b"fchownat",
261: b"futimesat",
262: b"newfstatat",
263: b"unlinkat",
264: b"renameat",
265: b"linkat",
266: b"symlinkat",
267: b"readlinkat",
268: b"fchmodat",
269: b"faccessat",
270: b"pselect6",
271: b"ppoll",
272: b"unshare",
273: b"set_robust_list",
274: b"get_robust_list",
275: b"splice",
276: b"tee",
277: b"sync_file_range",
278: b"vmsplice",
279: b"move_pages",
280: b"utimensat",
281: b"epoll_pwait",
282: b"signalfd",
283: b"timerfd_create",
284: b"eventfd",
285: b"fallocate",
286: b"timerfd_settime",
287: b"timerfd_gettime",
288: b"accept4",
289: b"signalfd4",
290: b"eventfd2",
291: b"epoll_create1",
292: b"dup3",
293: b"pipe2",
294: b"inotify_init1",
295: b"preadv",
296: b"pwritev",
297: b"rt_tgsigqueueinfo",
298: b"perf_event_open",
299: b"recvmmsg",
300: b"fanotify_init",
301: b"fanotify_mark",
302: b"prlimit64",
303: b"name_to_handle_at",
304: b"open_by_handle_at",
305: b"clock_adjtime",
306: b"syncfs",
307: b"sendmmsg",
308: b"setns",
309: b"getcpu",
310: b"process_vm_readv",
311: b"process_vm_writev",
312: b"kcmp",
313: b"finit_module",
}
# Try to use ausyscall if it is available, because it can give us an up-to-date
# list of syscalls for various architectures, rather than the x86-64 hardcoded
# list above.
def parse_syscall(line):
parts = line.split()
return (int(parts[0]), parts[1].strip())
try:
# Skip the first line, which is a header. The rest of the lines are simply
# SYSCALL_NUM\tSYSCALL_NAME pairs.
out = subprocess.check_output('ausyscall --dump | tail -n +2', shell=True)
syscalls = dict(map(parse_syscall, out.strip().split(b'\n')))
except Exception as e:
if platform.machine() == "x86_64":
pass
else:
raise Exception("ausyscall: command not found")
# signal handler # signal handler
def signal_ignore(signal, frame): def signal_ignore(signal, frame):
print() print()
...@@ -526,7 +179,7 @@ def agg_colval(key): ...@@ -526,7 +179,7 @@ def agg_colval(key):
if args.process: if args.process:
return b"%-6d %-15s" % (key.value, comm_for_pid(key.value)) return b"%-6d %-15s" % (key.value, comm_for_pid(key.value))
else: else:
return syscalls.get(key.value, b"[unknown: %d]" % key.value) return syscall_name(key.value)
def print_count_stats(): def print_count_stats():
data = bpf["data"] data = bpf["data"]
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment