blob: 926166fbbce8e00557df46d3dc7558758bd611ad [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* 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.
*/
#include "src/trace_processor/syscall_tracker.h"
#include <utility>
#include <inttypes.h>
#include "src/trace_processor/slice_tracker.h"
#include "src/trace_processor/stats.h"
namespace perfetto {
namespace trace_processor {
namespace {
// Syscall number to string.
// https://thog.github.io/syscalls-table-aarch64/latest.html
constexpr std::array<const char*, kSyscallCount> aarch64_to_syscall = {{
"sys_io_setup", //
"sys_io_destroy", //
"sys_io_submit", //
"sys_io_cancel", //
"sys_io_getevents", //
"sys_setxattr", //
"sys_lsetxattr", //
"sys_fsetxattr", //
"sys_getxattr", //
"sys_lgetxattr", //
"sys_fgetxattr", //
"sys_listxattr", //
"sys_llistxattr", //
"sys_flistxattr", //
"sys_removexattr", //
"sys_lremovexattr", //
"sys_fremovexattr", //
"sys_getcwd", //
"sys_lookup_dcookie", //
"sys_eventfd2", //
"sys_epoll_create1", //
"sys_epoll_ctl", //
"sys_epoll_pwait", //
"sys_dup", //
"sys_dup3", //
"sys_inotify_init1", //
"sys_inotify_add_watch", //
"sys_inotify_rm_watch", //
"sys_ioctl", //
"sys_ioprio_set", //
"sys_ioprio_get", //
"sys_flock", //
"sys_mknodat", //
"sys_mkdirat", //
"sys_unlinkat", //
"sys_symlinkat", //
"sys_linkat", //
"sys_renameat", //
"sys_umount2", //
"sys_mount", //
"sys_pivot_root", //
"sys_nfsservctl", //
"sys_fallocate", //
"sys_faccessat", //
"sys_chdir", //
"sys_fchdir", //
"sys_chroot", //
"sys_fchmod", //
"sys_fchmodat", //
"sys_fchownat", //
"sys_fchown", //
"sys_openat", //
"sys_close", //
"sys_vhangup", //
"sys_pipe2", //
"sys_quotactl", //
"sys_getdents64", //
"sys_read", //
"sys_write", //
"sys_readv", //
"sys_writev", //
"sys_pread64", //
"sys_pwrite64", //
"sys_preadv", //
"sys_pwritev", //
"sys_pselect6", //
"sys_ppoll", //
"sys_signalfd4", //
"sys_vmsplice", //
"sys_splice", //
"sys_tee", //
"sys_readlinkat", //
"sys_sync", //
"sys_fsync", //
"sys_fdatasync", //
"sys_sync_file_range2", //
"sys_sync_file_range", //
"sys_timerfd_create", //
"sys_timerfd_settime", //
"sys_timerfd_gettime", //
"sys_utimensat", //
"sys_acct", //
"sys_capget", //
"sys_capset", //
"sys_personality", //
"sys_exit", //
"sys_exit_group", //
"sys_waitid", //
"sys_set_tid_address", //
"sys_unshare", //
"sys_futex", //
"sys_set_robust_list", //
"sys_get_robust_list", //
"sys_nanosleep", //
"sys_getitimer", //
"sys_setitimer", //
"sys_kexec_load", //
"sys_init_module", //
"sys_delete_module", //
"sys_timer_create", //
"sys_timer_gettime", //
"sys_timer_getoverrun", //
"sys_timer_settime", //
"sys_timer_delete", //
"sys_clock_settime", //
"sys_clock_gettime", //
"sys_clock_getres", //
"sys_clock_nanosleep", //
"sys_syslog", //
"sys_ptrace", //
"sys_sched_setparam", //
"sys_sched_setscheduler", //
"sys_sched_getscheduler", //
"sys_sched_getparam", //
"sys_sched_setaffinity", //
"sys_sched_getaffinity", //
"sys_sched_yield", //
"sys_sched_get_priority_max", //
"sys_sched_get_priority_min", //
"sys_sched_rr_get_interval", //
"sys_restart_syscall", //
"sys_kill", //
"sys_tkill", //
"sys_tgkill", //
"sys_sigaltstack", //
"sys_rt_sigsuspend", //
"sys_rt_sigaction", //
"sys_rt_sigprocmask", //
"sys_rt_sigpending", //
"sys_rt_sigtimedwait", //
"sys_rt_sigqueueinfo", //
"sys_rt_sigreturn", //
"sys_setpriority", //
"sys_getpriority", //
"sys_reboot", //
"sys_setregid", //
"sys_setgid", //
"sys_setreuid", //
"sys_setuid", //
"sys_setresuid", //
"sys_getresuid", //
"sys_setresgid", //
"sys_getresgid", //
"sys_setfsuid", //
"sys_setfsgid", //
"sys_times", //
"sys_setpgid", //
"sys_getpgid", //
"sys_getsid", //
"sys_setsid", //
"sys_getgroups", //
"sys_setgroups", //
"sys_uname", //
"sys_sethostname", //
"sys_setdomainname", //
"sys_getrlimit", //
"sys_setrlimit", //
"sys_getrusage", //
"sys_umask", //
"sys_prctl", //
"sys_getcpu", //
"sys_gettimeofday", //
"sys_settimeofday", //
"sys_adjtimex", //
"sys_getpid", //
"sys_getppid", //
"sys_getuid", //
"sys_geteuid", //
"sys_getgid", //
"sys_getegid", //
"sys_gettid", //
"sys_sysinfo", //
"sys_mq_open", //
"sys_mq_unlink", //
"sys_mq_timedsend", //
"sys_mq_timedreceive", //
"sys_mq_notify", //
"sys_mq_getsetattr", //
"sys_msgget", //
"sys_msgctl", //
"sys_msgrcv", //
"sys_msgsnd", //
"sys_semget", //
"sys_semctl", //
"sys_semtimedop", //
"sys_semop", //
"sys_shmget", //
"sys_shmctl", //
"sys_shmat", //
"sys_shmdt", //
"sys_socket", //
"sys_socketpair", //
"sys_bind", //
"sys_listen", //
"sys_accept", //
"sys_connect", //
"sys_getsockname", //
"sys_getpeername", //
"sys_sendto", //
"sys_recvfrom", //
"sys_setsockopt", //
"sys_getsockopt", //
"sys_shutdown", //
"sys_sendmsg", //
"sys_recvmsg", //
"sys_readahead", //
"sys_brk", //
"sys_munmap", //
"sys_mremap", //
"sys_add_key", //
"sys_request_key", //
"sys_keyctl", //
"sys_clone", //
"sys_execve", //
"sys_swapon", //
"sys_swapoff", //
"sys_mprotect", //
"sys_msync", //
"sys_mlock", //
"sys_munlock", //
"sys_mlockall", //
"sys_munlockall", //
"sys_mincore", //
"sys_madvise", //
"sys_remap_file_pages", //
"sys_mbind", //
"sys_get_mempolicy", //
"sys_set_mempolicy", //
"sys_migrate_pages", //
"sys_move_pages", //
"sys_rt_tgsigqueueinfo", //
"sys_perf_event_open", //
"sys_accept4", //
"sys_recvmmsg", //
"sys_arch_specific_syscall", //
"sys_wait4", //
"sys_prlimit64", //
"sys_fanotify_init", //
"sys_fanotify_mark", //
"sys_name_to_handle_at", //
"sys_open_by_handle_at", //
"sys_clock_adjtime", //
"sys_syncfs", //
"sys_setns", //
"sys_sendmmsg", //
"sys_process_vm_readv", //
"sys_process_vm_writev", //
"sys_kcmp", //
"sys_finit_module", //
"sys_sched_setattr", //
"sys_sched_getattr", //
"sys_renameat2", //
"sys_seccomp", //
"sys_getrandom", //
"sys_memfd_create", //
"sys_bpf", //
"sys_execveat", //
"sys_userfaultfd", //
"sys_membarrier", //
"sys_mlock2", //
"sys_copy_file_range", //
"sys_preadv2", //
"sys_pwritev2", //
"sys_pkey_mprotect", //
"sys_pkey_alloc", //
"sys_pkey_free", //
"sys_statx", //
}};
// Syscall number to string.
// https://filippo.io/linux-syscall-table/
// http://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/
constexpr std::array<const char*, kSyscallCount> x86_64_to_syscall = {{
"sys_read", //
"sys_write", //
"sys_open", //
"sys_close", //
"sys_newstat", //
"sys_newfstat", //
"sys_newlstat", //
"sys_poll", //
"sys_lseek", //
"sys_mmap", //
"sys_mprotect", //
"sys_munmap", //
"sys_brk", //
"sys_rt_sigaction", //
"sys_rt_sigprocmask", //
"stub_rt_sigreturn", //
"sys_ioctl", //
"sys_pread64", //
"sys_pwrite64", //
"sys_readv", //
"sys_writev", //
"sys_access", //
"sys_pipe", //
"sys_select", //
"sys_sched_yield", //
"sys_mremap", //
"sys_msync", //
"sys_mincore", //
"sys_madvise", //
"sys_shmget", //
"sys_shmat", //
"sys_shmctl", //
"sys_dup", //
"sys_dup2", //
"sys_pause", //
"sys_nanosleep", //
"sys_getitimer", //
"sys_alarm", //
"sys_setitimer", //
"sys_getpid", //
"sys_sendfile64", //
"sys_socket", //
"sys_connect", //
"sys_accept", //
"sys_sendto", //
"sys_recvfrom", //
"sys_sendmsg", //
"sys_recvmsg", //
"sys_shutdown", //
"sys_bind", //
"sys_listen", //
"sys_getsockname", //
"sys_getpeername", //
"sys_socketpair", //
"sys_setsockopt", //
"sys_getsockopt", //
"stub_clone", //
"stub_fork", //
"stub_vfork", //
"stub_execve", //
"sys_exit", //
"sys_wait4", //
"sys_kill", //
"sys_newuname", //
"sys_semget", //
"sys_semop", //
"sys_semctl", //
"sys_shmdt", //
"sys_msgget", //
"sys_msgsnd", //
"sys_msgrcv", //
"sys_msgctl", //
"sys_fcntl", //
"sys_flock", //
"sys_fsync", //
"sys_fdatasync", //
"sys_truncate", //
"sys_ftruncate", //
"sys_getdents", //
"sys_getcwd", //
"sys_chdir", //
"sys_fchdir", //
"sys_rename", //
"sys_mkdir", //
"sys_rmdir", //
"sys_creat", //
"sys_link", //
"sys_unlink", //
"sys_symlink", //
"sys_readlink", //
"sys_chmod", //
"sys_fchmod", //
"sys_chown", //
"sys_fchown", //
"sys_lchown", //
"sys_umask", //
"sys_gettimeofday", //
"sys_getrlimit", //
"sys_getrusage", //
"sys_sysinfo", //
"sys_times", //
"sys_ptrace", //
"sys_getuid", //
"sys_syslog", //
"sys_getgid", //
"sys_setuid", //
"sys_setgid", //
"sys_geteuid", //
"sys_getegid", //
"sys_setpgid", //
"sys_getppid", //
"sys_getpgrp", //
"sys_setsid", //
"sys_setreuid", //
"sys_setregid", //
"sys_getgroups", //
"sys_setgroups", //
"sys_setresuid", //
"sys_getresuid", //
"sys_setresgid", //
"sys_getresgid", //
"sys_getpgid", //
"sys_setfsuid", //
"sys_setfsgid", //
"sys_getsid", //
"sys_capget", //
"sys_capset", //
"sys_rt_sigpending", //
"sys_rt_sigtimedwait", //
"sys_rt_sigqueueinfo", //
"sys_rt_sigsuspend", //
"sys_sigaltstack", //
"sys_utime", //
"sys_mknod", //
"", // uselib
"sys_personality", //
"sys_ustat", //
"sys_statfs", //
"sys_fstatfs", //
"sys_sysfs", //
"sys_getpriority", //
"sys_setpriority", //
"sys_sched_setparam", //
"sys_sched_getparam", //
"sys_sched_setscheduler", //
"sys_sched_getscheduler", //
"sys_sched_get_priority_max", //
"sys_sched_get_priority_min", //
"sys_sched_rr_get_interval", //
"sys_mlock", //
"sys_munlock", //
"sys_mlockall", //
"sys_munlockall", //
"sys_vhangup", //
"sys_modify_ldt", //
"sys_pivot_root", //
"sys_sysctl", //
"sys_prctl", //
"sys_arch_prctl", //
"sys_adjtimex", //
"sys_setrlimit", //
"sys_chroot", //
"sys_sync", //
"sys_acct", //
"sys_settimeofday", //
"sys_mount", //
"sys_umount", //
"sys_swapon", //
"sys_swapoff", //
"sys_reboot", //
"sys_sethostname", //
"sys_setdomainname", //
"stub_iopl", //
"sys_ioperm", //
"", // create_module
"sys_init_module", //
"sys_delete_module", //
"", // get_kernel_syms
"", // query_module
"sys_quotactl", //
"", // nfsservctl
"", // getpmsg
"", // putpmsg
"", // afs_syscall
"", // tuxcall
"", // security
"sys_gettid", //
"sys_readahead", //
"sys_setxattr", //
"sys_lsetxattr", //
"sys_fsetxattr", //
"sys_getxattr", //
"sys_lgetxattr", //
"sys_fgetxattr", //
"sys_listxattr", //
"sys_llistxattr", //
"sys_flistxattr", //
"sys_removexattr", //
"sys_lremovexattr", //
"sys_fremovexattr", //
"sys_tkill", //
"sys_time", //
"sys_futex", //
"sys_sched_setaffinity", //
"sys_sched_getaffinity", //
"", // set_thread_area
"sys_io_setup", //
"sys_io_destroy", //
"sys_io_getevents", //
"sys_io_submit", //
"sys_io_cancel", //
"", // get_thread_area
"sys_lookup_dcookie", //
"sys_epoll_create", //
"", // epoll_ctl_old
"", // epoll_wait_old
"sys_remap_file_pages", //
"sys_getdents64", //
"sys_set_tid_address", //
"sys_restart_syscall", //
"sys_semtimedop", //
"sys_fadvise64", //
"sys_timer_create", //
"sys_timer_settime", //
"sys_timer_gettime", //
"sys_timer_getoverrun", //
"sys_timer_delete", //
"sys_clock_settime", //
"sys_clock_gettime", //
"sys_clock_getres", //
"sys_clock_nanosleep", //
"sys_exit_group", //
"sys_epoll_wait", //
"sys_epoll_ctl", //
"sys_tgkill", //
"sys_utimes", //
"", // vserver
"sys_mbind", //
"sys_set_mempolicy", //
"sys_get_mempolicy", //
"sys_mq_open", //
"sys_mq_unlink", //
"sys_mq_timedsend", //
"sys_mq_timedreceive", //
"sys_mq_notify", //
"sys_mq_getsetattr", //
"sys_kexec_load", //
"sys_waitid", //
"sys_add_key", //
"sys_request_key", //
"sys_keyctl", //
"sys_ioprio_set", //
"sys_ioprio_get", //
"sys_inotify_init", //
"sys_inotify_add_watch", //
"sys_inotify_rm_watch", //
"sys_migrate_pages", //
"sys_openat", //
"sys_mkdirat", //
"sys_mknodat", //
"sys_fchownat", //
"sys_futimesat", //
"sys_newfstatat", //
"sys_unlinkat", //
"sys_renameat", //
"sys_linkat", //
"sys_symlinkat", //
"sys_readlinkat", //
"sys_fchmodat", //
"sys_faccessat", //
"sys_pselect6", //
"sys_ppoll", //
"sys_unshare", //
"sys_set_robust_list", //
"sys_get_robust_list", //
"sys_splice", //
"sys_tee", //
"sys_sync_file_range", //
"sys_vmsplice", //
"sys_move_pages", //
"sys_utimensat", //
"sys_epoll_pwait", //
"sys_signalfd", //
"sys_timerfd_create", //
"sys_eventfd", //
"sys_fallocate", //
"sys_timerfd_settime", //
"sys_timerfd_gettime", //
"sys_accept4", //
"sys_signalfd4", //
"sys_eventfd2", //
"sys_epoll_create1", //
"sys_dup3", //
"sys_pipe2", //
"sys_inotify_init1", //
"sys_preadv", //
"sys_pwritev", //
"sys_rt_tgsigqueueinfo", //
"sys_perf_event_open", //
"sys_recvmmsg", //
"sys_fanotify_init", //
"sys_fanotify_mark", //
"sys_prlimit64", //
"sys_name_to_handle_at", //
"sys_open_by_handle_at", //
"sys_clock_adjtime", //
"sys_syncfs", //
"sys_sendmmsg", //
"sys_setns", //
"sys_getcpu", //
"sys_process_vm_readv", //
"sys_process_vm_writev", //
"sys_kcmp", //
"sys_finit_module", //
}};
// When we don't know the architecture map every syscall number to
// null string.
constexpr std::array<const char*, kSyscallCount> unknown_to_syscall = {{}};
} // namespace
SyscallTracker::SyscallTracker(TraceProcessorContext* context)
: context_(context) {
// This sets arch_syscall_to_string_id_
SetArchitecture(kUnknown);
}
SyscallTracker::~SyscallTracker() = default;
void SyscallTracker::SetArchitecture(Architecture arch) {
const std::array<const char*, kSyscallCount>* arch_to_generic_syscall_number;
switch (arch) {
case kAarch64:
arch_to_generic_syscall_number = &aarch64_to_syscall;
break;
case kX86_64:
arch_to_generic_syscall_number = &x86_64_to_syscall;
break;
case kUnknown:
arch_to_generic_syscall_number = &unknown_to_syscall;
break;
}
for (size_t i = 0; i < kSyscallCount; i++) {
const char* name = (*arch_to_generic_syscall_number)[i];
StringId id =
context_->storage->InternString(name ? name : "UNKNOWN_SYSCALL");
arch_syscall_to_string_id_[i] = id;
if (name && !strcmp(name, "sys_write"))
sys_write_string_id_ = id;
}
}
void SyscallTracker::Enter(int64_t ts, UniqueTid utid, uint32_t syscall_num) {
StringId name = SyscallNumberToStringId(syscall_num);
if (!name) {
context_->storage->IncrementStats(stats::sys_unknown_syscall);
return;
}
context_->slice_tracker->Begin(ts, utid, 0 /* cat */, name);
}
void SyscallTracker::Exit(int64_t ts, UniqueTid utid, uint32_t syscall_num) {
StringId name = SyscallNumberToStringId(syscall_num);
if (!name) {
context_->storage->IncrementStats(stats::sys_unknown_syscall);
return;
}
context_->slice_tracker->End(ts, utid, 0 /* cat */, name);
}
} // namespace trace_processor
} // namespace perfetto