1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 08:57:35 +00:00

Kernel: Implement a simple process time profiler

The kernel now supports basic profiling of all the threads in a process
by calling profiling_enable(pid_t). You finish the profiling by calling
profiling_disable(pid_t).

This all works by recording thread stacks when the timer interrupt
fires and the current thread is in a process being profiled.
Note that symbolication is deferred until profiling_disable() to avoid
adding more noise than necessary to the profile.

A simple "/bin/profile" command is included here that can be used to
start/stop profiling like so:

    $ profile 10 on
    ... wait ...
    $ profile 10 off

After a profile has been recorded, it can be fetched in /proc/profile

There are various limits (or "bugs") on this mechanism at the moment:

- Only one process can be profiled at a time.
- We allocate 8MB for the samples, if you use more space, things will
  not work, and probably break a bit.
- Things will probably fall apart if the profiled process dies during
  profiling, or while extracing /proc/profile
This commit is contained in:
Andreas Kling 2019-12-11 20:36:56 +01:00
parent adb1870628
commit b32e961a84
13 changed files with 388 additions and 135 deletions

View file

@ -13,141 +13,143 @@ struct sockaddr;
typedef u32 socklen_t;
}
#define ENUMERATE_SYSCALLS \
__ENUMERATE_SYSCALL(sleep) \
__ENUMERATE_SYSCALL(yield) \
__ENUMERATE_SYSCALL(putch) \
__ENUMERATE_SYSCALL(open) \
__ENUMERATE_SYSCALL(close) \
__ENUMERATE_SYSCALL(read) \
__ENUMERATE_SYSCALL(lseek) \
__ENUMERATE_SYSCALL(kill) \
__ENUMERATE_SYSCALL(getuid) \
__ENUMERATE_SYSCALL(exit) \
__ENUMERATE_SYSCALL(getgid) \
__ENUMERATE_SYSCALL(getpid) \
__ENUMERATE_SYSCALL(waitpid) \
__ENUMERATE_SYSCALL(mmap) \
__ENUMERATE_SYSCALL(munmap) \
__ENUMERATE_SYSCALL(get_dir_entries) \
__ENUMERATE_SYSCALL(lstat) \
__ENUMERATE_SYSCALL(getcwd) \
__ENUMERATE_SYSCALL(gettimeofday) \
__ENUMERATE_SYSCALL(gethostname) \
__ENUMERATE_SYSCALL(chdir) \
__ENUMERATE_SYSCALL(uname) \
__ENUMERATE_SYSCALL(set_mmap_name) \
__ENUMERATE_SYSCALL(readlink) \
__ENUMERATE_SYSCALL(write) \
__ENUMERATE_SYSCALL(ttyname_r) \
__ENUMERATE_SYSCALL(stat) \
__ENUMERATE_SYSCALL(getsid) \
__ENUMERATE_SYSCALL(setsid) \
__ENUMERATE_SYSCALL(getpgid) \
__ENUMERATE_SYSCALL(setpgid) \
__ENUMERATE_SYSCALL(getpgrp) \
__ENUMERATE_SYSCALL(fork) \
__ENUMERATE_SYSCALL(execve) \
__ENUMERATE_SYSCALL(geteuid) \
__ENUMERATE_SYSCALL(getegid) \
__ENUMERATE_REMOVED_SYSCALL(isatty) \
__ENUMERATE_SYSCALL(getdtablesize) \
__ENUMERATE_SYSCALL(dup) \
__ENUMERATE_SYSCALL(dup2) \
__ENUMERATE_SYSCALL(sigaction) \
__ENUMERATE_SYSCALL(getppid) \
__ENUMERATE_SYSCALL(umask) \
__ENUMERATE_SYSCALL(getgroups) \
__ENUMERATE_SYSCALL(setgroups) \
__ENUMERATE_SYSCALL(sigreturn) \
__ENUMERATE_SYSCALL(sigprocmask) \
__ENUMERATE_SYSCALL(sigpending) \
__ENUMERATE_SYSCALL(pipe) \
__ENUMERATE_SYSCALL(killpg) \
__ENUMERATE_SYSCALL(setuid) \
__ENUMERATE_SYSCALL(setgid) \
__ENUMERATE_SYSCALL(alarm) \
__ENUMERATE_SYSCALL(fstat) \
__ENUMERATE_SYSCALL(access) \
__ENUMERATE_SYSCALL(fcntl) \
__ENUMERATE_SYSCALL(ioctl) \
__ENUMERATE_SYSCALL(mkdir) \
__ENUMERATE_SYSCALL(times) \
__ENUMERATE_SYSCALL(utime) \
__ENUMERATE_SYSCALL(sync) \
__ENUMERATE_SYSCALL(ptsname_r) \
__ENUMERATE_SYSCALL(select) \
__ENUMERATE_SYSCALL(unlink) \
__ENUMERATE_SYSCALL(poll) \
__ENUMERATE_SYSCALL(read_tsc) \
__ENUMERATE_SYSCALL(rmdir) \
__ENUMERATE_SYSCALL(chmod) \
__ENUMERATE_SYSCALL(usleep) \
__ENUMERATE_SYSCALL(socket) \
__ENUMERATE_SYSCALL(bind) \
__ENUMERATE_SYSCALL(accept) \
__ENUMERATE_SYSCALL(listen) \
__ENUMERATE_SYSCALL(connect) \
__ENUMERATE_SYSCALL(create_shared_buffer) \
__ENUMERATE_SYSCALL(share_buffer_with) \
__ENUMERATE_SYSCALL(get_shared_buffer) \
__ENUMERATE_SYSCALL(release_shared_buffer) \
__ENUMERATE_SYSCALL(link) \
__ENUMERATE_SYSCALL(chown) \
__ENUMERATE_SYSCALL(fchmod) \
__ENUMERATE_SYSCALL(symlink) \
__ENUMERATE_SYSCALL(restore_signal_mask) \
__ENUMERATE_SYSCALL(get_shared_buffer_size) \
__ENUMERATE_SYSCALL(seal_shared_buffer) \
__ENUMERATE_SYSCALL(sendto) \
__ENUMERATE_SYSCALL(recvfrom) \
__ENUMERATE_SYSCALL(getsockopt) \
__ENUMERATE_SYSCALL(setsockopt) \
__ENUMERATE_SYSCALL(create_thread) \
__ENUMERATE_SYSCALL(gettid) \
__ENUMERATE_SYSCALL(donate) \
__ENUMERATE_SYSCALL(rename) \
__ENUMERATE_SYSCALL(shm_open) \
__ENUMERATE_SYSCALL(shm_unlink) \
__ENUMERATE_SYSCALL(ftruncate) \
__ENUMERATE_SYSCALL(systrace) \
__ENUMERATE_SYSCALL(exit_thread) \
__ENUMERATE_SYSCALL(mknod) \
__ENUMERATE_SYSCALL(writev) \
__ENUMERATE_SYSCALL(beep) \
__ENUMERATE_SYSCALL(getsockname) \
__ENUMERATE_SYSCALL(getpeername) \
__ENUMERATE_SYSCALL(sched_setparam) \
__ENUMERATE_SYSCALL(sched_getparam) \
__ENUMERATE_SYSCALL(fchown) \
__ENUMERATE_SYSCALL(halt) \
__ENUMERATE_SYSCALL(reboot) \
__ENUMERATE_SYSCALL(mount) \
__ENUMERATE_SYSCALL(umount) \
__ENUMERATE_SYSCALL(dump_backtrace) \
__ENUMERATE_SYSCALL(dbgputch) \
__ENUMERATE_SYSCALL(dbgputstr) \
__ENUMERATE_SYSCALL(watch_file) \
__ENUMERATE_SYSCALL(share_buffer_globally) \
__ENUMERATE_SYSCALL(set_process_icon) \
__ENUMERATE_SYSCALL(mprotect) \
__ENUMERATE_SYSCALL(realpath) \
__ENUMERATE_SYSCALL(get_process_name) \
__ENUMERATE_SYSCALL(fchdir) \
__ENUMERATE_SYSCALL(getrandom) \
__ENUMERATE_SYSCALL(setkeymap) \
__ENUMERATE_SYSCALL(clock_gettime) \
__ENUMERATE_SYSCALL(clock_nanosleep) \
__ENUMERATE_SYSCALL(openat) \
__ENUMERATE_SYSCALL(join_thread) \
__ENUMERATE_SYSCALL(module_load) \
__ENUMERATE_SYSCALL(module_unload) \
__ENUMERATE_SYSCALL(detach_thread) \
__ENUMERATE_SYSCALL(set_thread_name) \
__ENUMERATE_SYSCALL(get_thread_name) \
__ENUMERATE_SYSCALL(madvise) \
__ENUMERATE_SYSCALL(purge) \
__ENUMERATE_SYSCALL(set_shared_buffer_volatile)
#define ENUMERATE_SYSCALLS \
__ENUMERATE_SYSCALL(sleep) \
__ENUMERATE_SYSCALL(yield) \
__ENUMERATE_SYSCALL(putch) \
__ENUMERATE_SYSCALL(open) \
__ENUMERATE_SYSCALL(close) \
__ENUMERATE_SYSCALL(read) \
__ENUMERATE_SYSCALL(lseek) \
__ENUMERATE_SYSCALL(kill) \
__ENUMERATE_SYSCALL(getuid) \
__ENUMERATE_SYSCALL(exit) \
__ENUMERATE_SYSCALL(getgid) \
__ENUMERATE_SYSCALL(getpid) \
__ENUMERATE_SYSCALL(waitpid) \
__ENUMERATE_SYSCALL(mmap) \
__ENUMERATE_SYSCALL(munmap) \
__ENUMERATE_SYSCALL(get_dir_entries) \
__ENUMERATE_SYSCALL(lstat) \
__ENUMERATE_SYSCALL(getcwd) \
__ENUMERATE_SYSCALL(gettimeofday) \
__ENUMERATE_SYSCALL(gethostname) \
__ENUMERATE_SYSCALL(chdir) \
__ENUMERATE_SYSCALL(uname) \
__ENUMERATE_SYSCALL(set_mmap_name) \
__ENUMERATE_SYSCALL(readlink) \
__ENUMERATE_SYSCALL(write) \
__ENUMERATE_SYSCALL(ttyname_r) \
__ENUMERATE_SYSCALL(stat) \
__ENUMERATE_SYSCALL(getsid) \
__ENUMERATE_SYSCALL(setsid) \
__ENUMERATE_SYSCALL(getpgid) \
__ENUMERATE_SYSCALL(setpgid) \
__ENUMERATE_SYSCALL(getpgrp) \
__ENUMERATE_SYSCALL(fork) \
__ENUMERATE_SYSCALL(execve) \
__ENUMERATE_SYSCALL(geteuid) \
__ENUMERATE_SYSCALL(getegid) \
__ENUMERATE_REMOVED_SYSCALL(isatty) \
__ENUMERATE_SYSCALL(getdtablesize) \
__ENUMERATE_SYSCALL(dup) \
__ENUMERATE_SYSCALL(dup2) \
__ENUMERATE_SYSCALL(sigaction) \
__ENUMERATE_SYSCALL(getppid) \
__ENUMERATE_SYSCALL(umask) \
__ENUMERATE_SYSCALL(getgroups) \
__ENUMERATE_SYSCALL(setgroups) \
__ENUMERATE_SYSCALL(sigreturn) \
__ENUMERATE_SYSCALL(sigprocmask) \
__ENUMERATE_SYSCALL(sigpending) \
__ENUMERATE_SYSCALL(pipe) \
__ENUMERATE_SYSCALL(killpg) \
__ENUMERATE_SYSCALL(setuid) \
__ENUMERATE_SYSCALL(setgid) \
__ENUMERATE_SYSCALL(alarm) \
__ENUMERATE_SYSCALL(fstat) \
__ENUMERATE_SYSCALL(access) \
__ENUMERATE_SYSCALL(fcntl) \
__ENUMERATE_SYSCALL(ioctl) \
__ENUMERATE_SYSCALL(mkdir) \
__ENUMERATE_SYSCALL(times) \
__ENUMERATE_SYSCALL(utime) \
__ENUMERATE_SYSCALL(sync) \
__ENUMERATE_SYSCALL(ptsname_r) \
__ENUMERATE_SYSCALL(select) \
__ENUMERATE_SYSCALL(unlink) \
__ENUMERATE_SYSCALL(poll) \
__ENUMERATE_SYSCALL(read_tsc) \
__ENUMERATE_SYSCALL(rmdir) \
__ENUMERATE_SYSCALL(chmod) \
__ENUMERATE_SYSCALL(usleep) \
__ENUMERATE_SYSCALL(socket) \
__ENUMERATE_SYSCALL(bind) \
__ENUMERATE_SYSCALL(accept) \
__ENUMERATE_SYSCALL(listen) \
__ENUMERATE_SYSCALL(connect) \
__ENUMERATE_SYSCALL(create_shared_buffer) \
__ENUMERATE_SYSCALL(share_buffer_with) \
__ENUMERATE_SYSCALL(get_shared_buffer) \
__ENUMERATE_SYSCALL(release_shared_buffer) \
__ENUMERATE_SYSCALL(link) \
__ENUMERATE_SYSCALL(chown) \
__ENUMERATE_SYSCALL(fchmod) \
__ENUMERATE_SYSCALL(symlink) \
__ENUMERATE_SYSCALL(restore_signal_mask) \
__ENUMERATE_SYSCALL(get_shared_buffer_size) \
__ENUMERATE_SYSCALL(seal_shared_buffer) \
__ENUMERATE_SYSCALL(sendto) \
__ENUMERATE_SYSCALL(recvfrom) \
__ENUMERATE_SYSCALL(getsockopt) \
__ENUMERATE_SYSCALL(setsockopt) \
__ENUMERATE_SYSCALL(create_thread) \
__ENUMERATE_SYSCALL(gettid) \
__ENUMERATE_SYSCALL(donate) \
__ENUMERATE_SYSCALL(rename) \
__ENUMERATE_SYSCALL(shm_open) \
__ENUMERATE_SYSCALL(shm_unlink) \
__ENUMERATE_SYSCALL(ftruncate) \
__ENUMERATE_SYSCALL(systrace) \
__ENUMERATE_SYSCALL(exit_thread) \
__ENUMERATE_SYSCALL(mknod) \
__ENUMERATE_SYSCALL(writev) \
__ENUMERATE_SYSCALL(beep) \
__ENUMERATE_SYSCALL(getsockname) \
__ENUMERATE_SYSCALL(getpeername) \
__ENUMERATE_SYSCALL(sched_setparam) \
__ENUMERATE_SYSCALL(sched_getparam) \
__ENUMERATE_SYSCALL(fchown) \
__ENUMERATE_SYSCALL(halt) \
__ENUMERATE_SYSCALL(reboot) \
__ENUMERATE_SYSCALL(mount) \
__ENUMERATE_SYSCALL(umount) \
__ENUMERATE_SYSCALL(dump_backtrace) \
__ENUMERATE_SYSCALL(dbgputch) \
__ENUMERATE_SYSCALL(dbgputstr) \
__ENUMERATE_SYSCALL(watch_file) \
__ENUMERATE_SYSCALL(share_buffer_globally) \
__ENUMERATE_SYSCALL(set_process_icon) \
__ENUMERATE_SYSCALL(mprotect) \
__ENUMERATE_SYSCALL(realpath) \
__ENUMERATE_SYSCALL(get_process_name) \
__ENUMERATE_SYSCALL(fchdir) \
__ENUMERATE_SYSCALL(getrandom) \
__ENUMERATE_SYSCALL(setkeymap) \
__ENUMERATE_SYSCALL(clock_gettime) \
__ENUMERATE_SYSCALL(clock_nanosleep) \
__ENUMERATE_SYSCALL(openat) \
__ENUMERATE_SYSCALL(join_thread) \
__ENUMERATE_SYSCALL(module_load) \
__ENUMERATE_SYSCALL(module_unload) \
__ENUMERATE_SYSCALL(detach_thread) \
__ENUMERATE_SYSCALL(set_thread_name) \
__ENUMERATE_SYSCALL(get_thread_name) \
__ENUMERATE_SYSCALL(madvise) \
__ENUMERATE_SYSCALL(purge) \
__ENUMERATE_SYSCALL(set_shared_buffer_volatile) \
__ENUMERATE_SYSCALL(profiling_enable) \
__ENUMERATE_SYSCALL(profiling_disable)
namespace Syscall {