Linux strace - TOP 12 przykładów
Pragnę w tym artykule zestawić 12, w mojej ocenie najbardziej przydatnych wywołań programu monitorującego strace. Nie będę tutaj jednak wchodził w szczegóły tego, czym ten program jest, jak działa i jak analizować logi stworzone przy jego pomocy. Zostawię sobie tę problematykę na jeden z kolejnych wpisów. Tutaj chciałbym pozostawić jedynie listę praktycznych snippetów. Zachęcam do lektury.
Słowem wstępu
Choć na początku artykułu zaznaczyłem, że nie będzie to wpis poświęcony teorii stojącej za programem strace, to jednak kilka słów objaśniających, z czym ma się do czynienia, wypada powiedzieć. Zatem, ujmując sprawę najkrócej, strace pozwala na podgląd i analizę wywołań poleceń systemowych wydawanych przez wskazany proces, przy czym możemy strace’em proces taki uruchomić, bądź podłączyć się do już działającego. Jest to zatem jedno z podstawowych narzędzi administratora systemu, a także świetna pomoc w odrobaczaniu programów i szukaniu problemów wydajnościowych.
W całym artykule poza jednym przypadkiem analizuję polecenie pwd, które wyświetla obecną lokację w terminalu. Proszę zwrócić uwagę i może nawet zadziwić się przez moment, jak wiele poleceń systemowych jest wykonywanych przez, zdawałoby się, tak prostą komendę.
$ pwd /home/mateusz/Pulpit
1. Uruchomienie procesu i podstawowy podgląd poleceń systemowych
Zacznę od wywołania najprostszego, a mianowicie od uruchomienia procesu przy pomocy strace i podglądu wszystkich poleceń systemowych aż do jego zakończenia.
strace [polecenie]
$ strace pwd execve("/bin/pwd", ["pwd"], [/* 79 vars */]) = 0 brk(0) = 0x1b5f000 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=149391, ...}) = 0 mmap(NULL, 149391, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fdfe464d000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 read(3, "177ELF211���������3�>�1���P 2�����"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=1857312, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fdfe464c000 mmap(NULL, 3965632, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fdfe4087000 mprotect(0x7fdfe4245000, 2097152, PROT_NONE) = 0 mmap(0x7fdfe4445000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1be000) = 0x7fdfe4445000 mmap(0x7fdfe444b000, 17088, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fdfe444b000 close(3) = 0 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fdfe464a000 arch_prctl(ARCH_SET_FS, 0x7fdfe464a740) = 0 mprotect(0x7fdfe4445000, 16384, PROT_READ) = 0 mprotect(0x606000, 4096, PROT_READ) = 0 mprotect(0x7fdfe4672000, 4096, PROT_READ) = 0 munmap(0x7fdfe464d000, 149391) = 0 brk(0) = 0x1b5f000 brk(0x1b80000) = 0x1b80000 open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=8482320, ...}) = 0 mmap(NULL, 8482320, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fdfe3870000 close(3) = 0 getcwd("/home/mateusz/Pulpit", 4096) = 21 fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fdfe4671000 write(1, "/home/mateusz/Pulpitn", 21/home/mateusz/Pulpit ) = 21 close(1) = 0 munmap(0x7fdfe4671000, 4096) = 0 close(2) = 0 exit_group(0) = ? +++ exited with 0 +++
Zgodnie z zapowiedzią, log jest całkiem obszerny, dlatego w kolejnych przykładach będę nieco zawężać zakres informacji, starając się wyłuskać to, co rzeczywiście może mnie w danej sytuacji interesować.
2. Wyświetlenie logów tylko jednego polecenia systemowego
Spróbuję teraz ograniczyć log z poprzedniego przykładu wyłącznie do jednego polecenia systemowego, np. open().
strace -e trace=[nazwa polecenia systemowego] [polecenie]
$ strace -e trace=open pwd open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3 /home/mateusz/Pulpit +++ exited with 0 +++
Zdecydowanie mniejszy szum informacyjny, jeśli więc wiadomo, czego się szuka, warto pominąć niepotrzebne wywołania.
3. Wyświetlenie logów wyłącznie wskazanych poleceń systemowych
Przykład podobny do poprzedniego, z tą różnicą, że poproszę o logi z więcej niż jednego polecenia systemowego..
strace -e trace=[polecenia systemowe oddzielone przecinkiem] [polecenie]
$ strace -e trace=open,close pwd open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 close(3) = 0 open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 close(3) = 0 open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3 close(3) = 0 /home/mateusz/Pulpit close(1) = 0 close(2) = 0 +++ exited with 0 +++
4. Zapis logów do pliku
Kiedy potrzebna jest szczegółowa analiza całego logu, na przykład gdy poszukujemy bliżej nieokreślonego problemu, warto zapisać wyniki działania programu strace do pliku.
strace -o [plik wyjściowy] [polecenie]
$ strace -o straceOut.txt pwd /home/mateusz/Pulpit
$ cat straceOut.txt execve("/bin/pwd", ["pwd"], [/* 79 vars */]) = 0 brk(0) = 0x204f000 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=149391, ...}) = 0 mmap(NULL, 149391, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f5274075000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 read(3, "177ELF211���������3�>�1���P 2�����"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=1857312, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5274074000 mmap(NULL, 3965632, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f5273aaf000 mprotect(0x7f5273c6d000, 2097152, PROT_NONE) = 0 mmap(0x7f5273e6d000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1be000) = 0x7f5273e6d000 mmap(0x7f5273e73000, 17088, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f5273e73000 close(3) = 0 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5274072000 arch_prctl(ARCH_SET_FS, 0x7f5274072740) = 0 mprotect(0x7f5273e6d000, 16384, PROT_READ) = 0 mprotect(0x606000, 4096, PROT_READ) = 0 mprotect(0x7f527409a000, 4096, PROT_READ) = 0 munmap(0x7f5274075000, 149391) = 0 brk(0) = 0x204f000 brk(0x2070000) = 0x2070000 open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=8482320, ...}) = 0 mmap(NULL, 8482320, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f5273298000 close(3) = 0 getcwd("/home/mateusz/Pulpit", 4096) = 21 fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5274099000 write(1, "/home/mateusz/Pulpitn", 21) = 21 close(1) = 0 munmap(0x7f5274099000, 4096) = 0 close(2) = 0 exit_group(0) = ? +++ exited with 0 +++
5. Podłączanie się do istniejącego procesu
Do tej pory w każdym przykładzie inicjowałem proces razem z wywołaniem strace. Tym razem podłączę się do już istniejącego, przy pomocy numeru PID (więcej o pobieraniu numeru PID). Procesem tym jest polecenie top, któremu przypisane jest PID 18739. Proszę zwrócić uwagę, że tym razem należy wywołać strace na prawach admina.
sudo strace -p [numer PID procesu]
$ sudo strace -p 18739 pselect6(1, [0], NULL, NULL, {0, 868139653}, {[], 8}) = 0 (Timeout) openat(AT_FDCWD, "/proc", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3 getdents(3, /* 356 entries */, 32768) = 9072 stat("/proc/1", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0 open("/proc/1/stat", O_RDONLY) = 8 read(8, "1 (init) S 0 1 1 0 -1 4219136 62"..., 1024) = 178 close(8) = 0 open("/proc/1/statm", O_RDONLY) = 8 read(8, "8506 1145 675 62 0 480 0n", 1024) = 25 close(8) = 0 [...]
6. Śledzenie procesów potomnych
Czasem zachodzi potrzeba śledzenia poczynań nie tylko wskazanego procesu, ale również wszystkich innych procesów, które on wywołuje (procesy potomne).
sudo strace -f [polecenie]
$ strace -f pwd execve("/bin/pwd", ["pwd"], [/* 79 vars */]) = 0 brk(0) = 0x114a000 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=149391, ...}) = 0 mmap(NULL, 149391, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f574de99000 close(3) = 0 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 read(3, "177ELF211���������3�>�1���P 2�����"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=1857312, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f574de98000 mmap(NULL, 3965632, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f574d8d3000 mprotect(0x7f574da91000, 2097152, PROT_NONE) = 0 mmap(0x7f574dc91000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1be000) = 0x7f574dc91000 mmap(0x7f574dc97000, 17088, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f574dc97000 close(3) = 0 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f574de96000 arch_prctl(ARCH_SET_FS, 0x7f574de96740) = 0 mprotect(0x7f574dc91000, 16384, PROT_READ) = 0 mprotect(0x606000, 4096, PROT_READ) = 0 mprotect(0x7f574debe000, 4096, PROT_READ) = 0 munmap(0x7f574de99000, 149391) = 0 brk(0) = 0x114a000 brk(0x116b000) = 0x116b000 open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=8482320, ...}) = 0 mmap(NULL, 8482320, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f574d0bc000 close(3) = 0 getcwd("/home/mateusz/Pulpit", 4096) = 21 fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f574debd000 write(1, "/home/mateusz/Pulpitn", 21/home/mateusz/Pulpit ) = 21 close(1) = 0 munmap(0x7f574debd000, 4096) = 0 close(2) = 0 exit_group(0) = ? +++ exited with 0 +++
7. Sprawdzanie jakie inne programy otwiera proces
Pozostaję w kontekście poprzedniego przykładu, czyli śledzę procesy główny i potomne, zawężając jednak pytanie, do tego, jakie inne programy są uruchamiane przez nie uruchamiane. Bardzo przydatne wywołanie!
strace -fe trace=execve [polecenie]
$ strace -fe trace=execve pwd execve("/bin/pwd", ["pwd"], [/* 79 vars */]) = 0 /home/mateusz/Pulpit +++ exited with 0 +++
8. Dołączenie timestamp do logów wywołań
Czasem bardzo cenną informacją podczas analizy logów strace jest moment w czasie, kiedy dane polecenie systemowe zostało wywołane. Dołączenie znacznika czasu (timestamp) sprowadza się do dodania flagi do wywołania strace.
strace -t [polecenie]
$ strace -t pwd 07:10:49 execve("/bin/pwd", ["pwd"], [/* 79 vars */]) = 0 07:10:49 brk(0) = 0x1749000 07:10:49 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) 07:10:49 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) 07:10:49 open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 07:10:49 fstat(3, {st_mode=S_IFREG|0644, st_size=149391, ...}) = 0 07:10:49 mmap(NULL, 149391, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7fc9d0a000 07:10:49 close(3) = 0 07:10:49 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) 07:10:49 open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 07:10:49 read(3, "177ELF211���������3�>�1���P 2�����"..., 832) = 832 07:10:49 fstat(3, {st_mode=S_IFREG|0755, st_size=1857312, ...}) = 0 07:10:49 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7fc9d09000 07:10:49 mmap(NULL, 3965632, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7fc9744000 07:10:49 mprotect(0x7f7fc9902000, 2097152, PROT_NONE) = 0 07:10:49 mmap(0x7f7fc9b02000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1be000) = 0x7f7fc9b02000 07:10:49 mmap(0x7f7fc9b08000, 17088, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f7fc9b08000 07:10:49 close(3) = 0 07:10:49 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7fc9d07000 07:10:49 arch_prctl(ARCH_SET_FS, 0x7f7fc9d07740) = 0 07:10:49 mprotect(0x7f7fc9b02000, 16384, PROT_READ) = 0 07:10:49 mprotect(0x606000, 4096, PROT_READ) = 0 07:10:49 mprotect(0x7f7fc9d2f000, 4096, PROT_READ) = 0 07:10:49 munmap(0x7f7fc9d0a000, 149391) = 0 07:10:49 brk(0) = 0x1749000 07:10:49 brk(0x176a000) = 0x176a000 07:10:49 open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3 07:10:49 fstat(3, {st_mode=S_IFREG|0644, st_size=8482320, ...}) = 0 07:10:49 mmap(NULL, 8482320, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7fc8f2d000 07:10:49 close(3) = 0 07:10:49 getcwd("/home/mateusz/Pulpit", 4096) = 21 07:10:49 fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 07:10:49 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7fc9d2e000 07:10:49 write(1, "/home/mateusz/Pulpitn", 21/home/mateusz/Pulpit ) = 21 07:10:49 close(1) = 0 07:10:49 munmap(0x7f7fc9d2e000, 4096) = 0 07:10:49 close(2) = 0 07:10:49 exit_group(0) = ? 07:10:49 +++ exited with 0 +++
9. Dołączenie Linux-epoch timestamp do logów wywołań
Choć ja osobiście, nigdy z tego nie korzystałem, warto odnotować możliwość przedstawienia znaczników czasu w formacie czasu unixowego.
strace -ttt [polecenie]
$ strace -ttt pwd 1523509849.031836 execve("/bin/pwd", ["pwd"], [/* 79 vars */]) = 0 1523509849.032025 brk(0) = 0x1776000 1523509849.032057 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) 1523509849.032089 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) 1523509849.032116 open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 1523509849.032144 fstat(3, {st_mode=S_IFREG|0644, st_size=149391, ...}) = 0 1523509849.032171 mmap(NULL, 149391, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fe1a97a5000 1523509849.032198 close(3) = 0 1523509849.032223 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) 1523509849.032253 open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 1523509849.032279 read(3, "177ELF211���������3�>�1���P 2�����"..., 832) = 832 1523509849.032306 fstat(3, {st_mode=S_IFREG|0755, st_size=1857312, ...}) = 0 1523509849.032331 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe1a97a4000 1523509849.032362 mmap(NULL, 3965632, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fe1a91df000 1523509849.032387 mprotect(0x7fe1a939d000, 2097152, PROT_NONE) = 0 1523509849.032415 mmap(0x7fe1a959d000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1be000) = 0x7fe1a959d000 1523509849.032445 mmap(0x7fe1a95a3000, 17088, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fe1a95a3000 1523509849.032474 close(3) = 0 1523509849.032504 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe1a97a2000 1523509849.032531 arch_prctl(ARCH_SET_FS, 0x7fe1a97a2740) = 0 1523509849.032591 mprotect(0x7fe1a959d000, 16384, PROT_READ) = 0 1523509849.032618 mprotect(0x606000, 4096, PROT_READ) = 0 1523509849.032645 mprotect(0x7fe1a97ca000, 4096, PROT_READ) = 0 1523509849.032669 munmap(0x7fe1a97a5000, 149391) = 0 1523509849.032751 brk(0) = 0x1776000 1523509849.032773 brk(0x1797000) = 0x1797000 1523509849.032802 open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3 1523509849.032829 fstat(3, {st_mode=S_IFREG|0644, st_size=8482320, ...}) = 0 1523509849.032854 mmap(NULL, 8482320, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fe1a89c8000 1523509849.032882 close(3) = 0 1523509849.032928 getcwd("/home/mateusz/Pulpit", 4096) = 21 1523509849.032957 fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 1523509849.032983 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe1a97c9000 1523509849.033009 write(1, "/home/mateusz/Pulpitn", 21/home/mateusz/Pulpit ) = 21 1523509849.033044 close(1) = 0 1523509849.033067 munmap(0x7fe1a97c9000, 4096) = 0 1523509849.033092 close(2) = 0 1523509849.033116 exit_group(0) = ? 1523509849.033170 +++ exited with 0 +++
10. Dołączenie czasu trwania wywołań systemowych
Podczas analizy wydajności programu bardzo istotną informacją może być czas wykonywania każdego z poleceń systemowych.
strace -T [polecenie]
$ strace -T pwd execve("/bin/pwd", ["pwd"], [/* 79 vars */]) = 0 <0.000106> brk(0) = 0x1e44000 <0.000007> access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) <0.000009> access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) <0.000008> open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 <0.000009> fstat(3, {st_mode=S_IFREG|0644, st_size=149391, ...}) = 0 <0.000008> mmap(NULL, 149391, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f23b7b69000 <0.000008> close(3) = 0 <0.000007> access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) <0.000008> open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 <0.000009> read(3, "177ELF211���������3�>�1���P 2�����"..., 832) = 832 <0.000007> fstat(3, {st_mode=S_IFREG|0755, st_size=1857312, ...}) = 0 <0.000007> mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f23b7b68000 <0.000008> mmap(NULL, 3965632, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f23b75a3000 <0.000009> mprotect(0x7f23b7761000, 2097152, PROT_NONE) = 0 <0.000012> mmap(0x7f23b7961000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1be000) = 0x7f23b7961000 <0.000010> mmap(0x7f23b7967000, 17088, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f23b7967000 <0.000009> close(3) = 0 <0.000007> mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f23b7b66000 <0.000008> arch_prctl(ARCH_SET_FS, 0x7f23b7b66740) = 0 <0.000007> mprotect(0x7f23b7961000, 16384, PROT_READ) = 0 <0.000009> mprotect(0x606000, 4096, PROT_READ) = 0 <0.000008> mprotect(0x7f23b7b8e000, 4096, PROT_READ) = 0 <0.000008> munmap(0x7f23b7b69000, 149391) = 0 <0.000013> brk(0) = 0x1e44000 <0.000008> brk(0x1e65000) = 0x1e65000 <0.000008> open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3 <0.000010> fstat(3, {st_mode=S_IFREG|0644, st_size=8482320, ...}) = 0 <0.000007> mmap(NULL, 8482320, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f23b6d8c000 <0.000008> close(3) = 0 <0.000007> getcwd("/home/mateusz/Pulpit", 4096) = 21 <0.000008> fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 <0.000009> mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f23b7b8d000 <0.000009> write(1, "/home/mateusz/Pulpitn", 21/home/mateusz/Pulpit ) = 21 <0.000014> close(1) = 0 <0.000007> munmap(0x7f23b7b8d000, 4096) = 0 <0.000011> close(2) = 0 <0.000008> exit_group(0) = ? +++ exited with 0 +++
11. Dołączenie względnego czasu wywołań systemowych
W pewnych sytuacjach wygodnie będzie analizować logi, mając przed oczyma relatywny czas między początkami następujących po sobie poleceń.
strace -r [polecenie]
$ strace -r pwd 0.000000 execve("/bin/pwd", ["pwd"], [/* 79 vars */]) = 0 0.000194 brk(0) = 0x1bc6000 0.000036 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) 0.000048 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) 0.000026 open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 0.000025 fstat(3, {st_mode=S_IFREG|0644, st_size=149391, ...}) = 0 0.000025 mmap(NULL, 149391, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f8ccb1ca000 0.000024 close(3) = 0 0.000033 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) 0.000022 open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 0.000021 read(3, "177ELF211���������3�>�1���P 2�����"..., 832) = 832 0.000021 fstat(3, {st_mode=S_IFREG|0755, st_size=1857312, ...}) = 0 0.000020 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f8ccb1c9000 0.000024 mmap(NULL, 3965632, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f8ccac04000 0.000021 mprotect(0x7f8ccadc2000, 2097152, PROT_NONE) = 0 0.000022 mmap(0x7f8ccafc2000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1be000) = 0x7f8ccafc2000 0.000025 mmap(0x7f8ccafc8000, 17088, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f8ccafc8000 0.000023 close(3) = 0 0.000025 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f8ccb1c7000 0.000023 arch_prctl(ARCH_SET_FS, 0x7f8ccb1c7740) = 0 0.000056 mprotect(0x7f8ccafc2000, 16384, PROT_READ) = 0 0.000025 mprotect(0x606000, 4096, PROT_READ) = 0 0.000024 mprotect(0x7f8ccb1ef000, 4096, PROT_READ) = 0 0.000018 munmap(0x7f8ccb1ca000, 149391) = 0 0.000071 brk(0) = 0x1bc6000 0.000018 brk(0x1be7000) = 0x1be7000 0.000022 open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3 0.000023 fstat(3, {st_mode=S_IFREG|0644, st_size=8482320, ...}) = 0 0.000020 mmap(NULL, 8482320, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f8cca3ed000 0.000023 close(3) = 0 0.000043 getcwd("/home/mateusz/Pulpit", 4096) = 21 0.000022 fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 0.000020 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f8ccb1ee000 0.000022 write(1, "/home/mateusz/Pulpitn", 21/home/mateusz/Pulpit ) = 21 0.000030 close(1) = 0 0.000018 munmap(0x7f8ccb1ee000, 4096) = 0 0.000021 close(2) = 0 0.000018 exit_group(0) = ? 0.000046 +++ exited with 0 +++
12. Raport z czasu spędzonego na poszczególnych wywołaniach systemowych
Bardzo przydatne polecenie, szczególnie jeśli szuka się problemów wydajnościowych, a nie bardzo wiadomo, od czego zacząć. Dostaniemy listę poleceń systemowych uporządkowaną malejąco pod względem czasu w nich spędzonego, wraz z podaniem tego czasu (również wyrażonego procentowo, w stosunku do całego czasu pracy procesu), oraz liczbę wystąpień poszczególnych wywołań.
strace -c [polecenie]
$ strace -c pwd /home/mateusz/Pulpit % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 27.75 0.000048 16 3 open 21.97 0.000038 5 8 mmap 12.14 0.000021 7 3 3 access 9.25 0.000016 4 4 mprotect 7.51 0.000013 7 2 munmap 5.20 0.000009 2 5 close 4.62 0.000008 2 4 fstat 3.47 0.000006 2 3 brk 2.89 0.000005 5 1 write 1.73 0.000003 3 1 read 1.73 0.000003 3 1 execve 1.16 0.000002 2 1 getcwd 0.58 0.000001 1 1 arch_prctl ------ ----------- ----------- --------- --------- ---------------- 100.00 0.000173 37 3 total
Komentarze (0) - Nikt jeszcze nie komentował - bądź pierwszy!