Strace - Podsłuchiwanie procesów w Linuksie
Co to jest strace?
W świecie Linuksa, większość operacji, jakie wykonuje program – od otwarcia pliku, przez połączenie z siecią, aż po odczytanie czasu – odbywa się za pośrednictwem wywołań systemowych (system calls). Są to specjalne funkcje jądra, które programy “proszą” o wykonanie niskopoziomowych zadań.
strace (skrót od “system call trace”) to potężne narzędzie diagnostyczne, które pozwala na “podsłuchanie” i wyświetlenie wszystkich tych wywołań systemowych, jakie wykonuje dany proces w czasie rzeczywistym. Dzięki temu możemy dokładnie zobaczyć, co program robi “pod maską”.
Dlaczego strace jest tak użyteczny?
strace jest niezastąpiony w sytuacjach, gdy program nie działa tak, jak powinien, a jego własne logi nic nam nie mówią. Pozwala odpowiedzieć na pytania takie jak:
- Dlaczego ten program nie może otworzyć pliku? (Może szuka go w złej ścieżce? Może nie ma uprawnień?)
- Dlaczego ten program tak wolno działa? (Może ciągle próbuje połączyć się z niedostępnym adresem sieciowym?)
- Do jakich plików konfiguracyjnych odwołuje się ten proces?
Jak używać strace? Podstawowe zastosowania
1. Uruchamianie programu pod strace
Najprostszym sposobem użycia strace jest uruchomienie z nim dowolnego programu. strace wyświetli każde wywołanie systemowe wykonane przez ten program.
# Zobaczmy, co robi proste polecenie 'ls'
strace ls
Wynik będzie bardzo szczegółowy, ale już na pierwszy rzut oka zobaczymy wywołania takie jak openat() (otwieranie plików), read() (czytanie), write() (pisanie na standardowe wyjście) i close() (zamykanie plików).
2. Podpinanie się do działającego procesu
To najczęstszy i najbardziej użyteczny scenariusz. Jeśli masz już uruchomiony proces (np. serwer WWW, bazę danych), który sprawia problemy, możesz podpiąć się do niego za pomocą strace, podając jego identyfikator procesu (PID).
# Najpierw znajdź PID procesu (np. serwera nginx)
pidof nginx
# Załóżmy, że PID to 1234. Podpinamy się:
sudo strace -p 1234
Od tego momentu, każde wywołanie systemowe wykonane przez proces o PID 1234 zostanie wyświetlone w Twoim terminalu. Aby zakończyć, wciśnij Ctrl+C.
Praktyczne przykłady i przydatne opcje
Przykład: Program nie może znaleźć pliku
Wyobraź sobie, że program moj-program przy starcie zgłasza błąd “nie można otworzyć pliku konfiguracyjnego”, ale nie mówi, gdzie go szuka. Użyjmy strace, aby się tego dowiedzieć. Będziemy filtrować tylko wywołania związane z otwieraniem plików (openat).
strace -e trace=openat moj-program
Na wyjściu zobaczysz coś w stylu:
openat(AT_FDCWD, "/etc/moj-program.conf", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/user/.config/moj-program.conf", O_RDONLY) = -1 ENOENT (No such file or directory)
Teraz dokładnie wiesz, w jakich lokalizacjach program szukał swojego pliku konfiguracyjnego i dlaczego go nie znalazł.
Inne przydatne opcje strace
-o <plik>: Zapisuje wynik do pliku zamiast na ekran.sudo strace -p 1234 -o /tmp/strace.log-f: Śledzi również wszystkie procesy potomne (forks/clones). Bardzo ważne przy analizie złożonych aplikacji, jak serwery WWW.-t: Pokazuje czas wykonania każdego wywołania.-s <rozmiar>: Określa maksymalną długość wyświetlanych ciągów znaków (domyślnie skracane).-e trace=<zestaw>: Filtruje wywołania do konkretnego zestawu. Przykłady:trace=file: Tylko wywołania związane z plikami (open,read,write,close).trace=network: Tylko wywołania sieciowe.trace=process: Tylko wywołania związane z zarządzaniem procesami.
Podsumowanie
strace to potężne narzędzie, które daje Ci rentgenowski wgląd w działanie dowolnego programu. Choć na początku jego output może wydawać się przytłaczający, nauka filtrowania i interpretowania najważniejszych wywołań systemowych jest jedną z najbardziej opłacalnych inwestycji w Twoje umiejętności debugowania w systemie Linux. To narzędzie, które wielokrotnie uratuje Cię w trudnych sytuacjach.