Вы можете использовать strace .Во-первых, вы можете получить высокоуровневую сводку стоимости каждого типа системных вызовов.Вы можете получить это резюме, запустив strace -c
.Например, одним из возможных выходных данных является следующее:
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
90.07 0.000263 26 10 getdents
3.42 0.000010 0 1572 read
3.42 0.000010 0 762 1 stat
3.08 0.000009 0 1574 6 open
0.00 0.000000 0 11 write
0.00 0.000000 0 1569 close
0.00 0.000000 0 48 fstat
Значение % time
относится к общему времени ядра, а не к общему времени выполнения (ядро + пользователь).Это резюме говорит вам, что самые дорогие системные вызовы.Однако, если вам нужно определить, какие конкретные экземпляры системных вызовов наиболее дороги и какие аргументы им передаются, вы можете запустить strace -i -T
.Опция -i
показывает адреса команд для инструкций, которые выполняли системный вызов, а опция -T
- время, потраченное на системный вызов.Вывод может выглядеть следующим образом:
[00007f97f1b37367] open("myfile", O_RDONLY|O_CLOEXEC) = 3 <0.000020>
[00007f97f1b372f4] fstat(3, {st_mode=S_IFREG|0644, st_size=159776, ...}) = 0 <0.000018>
[00007f97f1b374ba] mmap(NULL, 159776, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f97f1d19000 <0.000019>
[00007f97f1b37467] close(3) = 0 <0.000018>
В первом столбце показаны адреса команд, во втором столбце показаны системные вызовы с их аргументами, в третьем столбце показано возвращаемое значение, а в последнем столбце указано время, затраченное наэтот системный вызов.Этот список упорядочен по динамическому вхождению системного вызова.Вы можете отфильтровать этот вывод, используя либо grep
, либо параметр -e
.Адреса команд могут помочь вам определить, где в исходном коде выполняются эти системные вызовы.Например, если длинная последовательность системных вызовов имеет один и тот же адрес, то есть большая вероятность, что у вас есть цикл где-то в коде, который содержит системный вызов.Если ваш исполняемый двоичный файл не является PIE , динамические адреса совпадают со статическими адресами, показанными objdump
.Но даже с PIE относительный порядок динамических адресов одинаков.Я не знаю, есть ли простой способ сопоставить эти системные вызовы со строками исходного кода.
Если вы хотите узнать что-то вроде «он тратит 80% своего времени в sys_write () на fd 13»то есть / some / file ", то вам нужно написать скрипт, который сначала извлекает возвращаемые значения всех вызовов open
и соответствующих аргументов имени файла, а затем суммирует время всех вызовов sys_write
, чей аргумент fd
равенравно некоторому значению.