Команда strace


Вспомните о том, что системный вызов является привилегированной операцией, 
которую процесс из пространства пользователя просит у ядра выполнить (напри­
мер, открытие файла и чтение данных из него). Утилита strace выводит список всех 
системных вызовов, которые осуществляет процесс. Чтобы увидеть это в действии, 
запустите такую команду:
$ strace cat /dev/null
Из главы 1 вы узнали о том, что, когда процесс собирается запустить другой 
процесс, он задействует системный вызов fork(), чтобы создать ответвленную ко­
пию, которая затем использует один из системных вызовов семейства exec(), чтобы 
запустить новую команду. Команда strace начинает работать с новым процессом 
(копией исходного процесса) сразу после вызова fork(). Следовательно, первые 
строки вывода данной команды должны показать команду execve() в действии, за 
которой следует вызов инициализации памяти, brk(), как приведено ниже:
execve("/bin/cat", ["cat", "/dev/null"], [/* 58 vars */]) = 0
brk(0) = 0x9b65000
Следующая часть вывода относится главным образом к загрузке совместно 
используемых библиотек. Можете пропустить это, если вы не стремитесь узнать 
о том, что делает система совместно используемых библиотек.
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 
0xb77b5000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
--snip--open("/lib/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\200^\1"..., 1024)= 1024
Кроме того, пропустите вывод до команды mmap включительно, пока не встрети­
те строки, подобные следующим:
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 6), ...}) = 0
open("/dev/null", O_RDONLY|O_LARGEFILE) = 3
fstat64(3, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0
fadvise64_64(3, 0, 0, POSIX_FADV_SEQUENTIAL)= 0
read(3,"", 32768) = 0
close(3) = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
Эта часть вывода показывает команду в действии. Сначала посмотрите на вызов 
open(), который открывает файл. Число 3 — результат, означающий успешное за­
вершение (это файловый дескриптор, который ядро возвращает после открытия 
файла). Под ним вы видите, где команда cat выполняет чтение из устройства /dev/
null (вызов read(), который также обладает файловым дескриптором 3). Считы­
вать больше нечего, поэтому команда закрывает файловый дескриптор и выходит 
с помощью вызова exit_group().
Что происходит, если возникает ошибка? Попробуйте запустить команду 
strace cat  not_a_file и посмотрите на системный вызов open() в результатах 
вывода:
open("not_a_file", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
Поскольку команде open() не удалось открыть файл, она возвратила значение -1, 
чтобы сообщить об ошибке. Видно, что команда strace выводит название ошибки 
и дает ее краткое описание.
Отсутствующие файлы являются наиболее частым источником ошибок в ко­
мандах Unix, поэтому если системный журнал и другая информация оказываются 
не слишком полезными, а обратиться больше не к чему, то команда strace может 
оказать существенную помощь. Ее можно применить даже для демонов, которые 
откреплены. Например, так:
$ strace -o crummyd_strace -ff crummyd
В данном примере параметр -o команды strace заносит в журнал действия лю­
бого дочернего процесса, который демон crummy породил в crummyd_strace.pid, где 
pid — это идентификатор дочернего процесса.