Kiedyś kolega powiedział mi, że ostatnią opcją, gdy nie udało się debugować wszystkiego w Linuksie, było użycie strace .
Próbowałem poznać naukę stojącą za tym dziwnym narzędziem, ale nie jestem guru administratora systemu i tak naprawdę nie uzyskałem rezultatów.
Więc,
- Co to dokładnie jest i co robi?
- Jak iw jakich przypadkach należy go stosować?
- Jak należy rozumieć i przetwarzać dane wyjściowe?
Krótko mówiąc , jak to działa?
man strace
że jest bardzo łatwy do odczytania i przydatny. (PS nie wiedział wczoraj o strace i nie jest ekspertem od Linuksa)Odpowiedzi:
Przegląd Strace Strace
może być postrzegane jako lekki debugger. Pozwala programistom / użytkownikom szybko dowiedzieć się, jak program wchodzi w interakcje z systemem operacyjnym. Odbywa się to poprzez monitorowanie połączeń i sygnałów systemowych.
Korzysta
dobrze, gdy nie masz kodu źródłowego lub nie chcesz, abyś naprawdę go przejrzał.
Przydatny także dla własnego kodu, jeśli nie masz ochoty otwierać GDB, ale chcesz zrozumieć interakcje zewnętrzne.
Dobre małe wprowadzenie
Natknąłem się na to wprowadzenie, aby użyć strace innego dnia: strace hello world
źródło
ltrace
stackoverflow.com/a/52012215/5884955-EFAULT
(Ups, tylko do odczytu bufor) lub-ENOENT
(ups, uruchomiono z niewłaściwego katalogu, w którym ścieżka względna nie działała).)Krótko mówiąc, strace śledzi wszystkie wywołania systemowe wydane przez program wraz z ich kodami powrotu. Pomyśl o takich rzeczach, jak operacje na plikach / gniazdach i o wiele bardziej niejasne.
Jest to najbardziej przydatne, jeśli masz pewną praktyczną znajomość języka C, ponieważ tutaj wywołania systemowe dokładniej oznaczałyby standardowe wywołania biblioteki C.
Powiedzmy, że twój program to / usr / local / bin / cough. Po prostu użyj:
lub
zapisać w „pliku_wyjściowym”.
Wszystkie dane wyjściowe strace przejdą do stderr (uwaga, sama objętość często prosi o przekierowanie do pliku). W najprostszych przypadkach Twój program przerwie działanie z błędem i będziesz mógł zobaczyć, gdzie są jego ostatnie interakcje z systemem operacyjnym w wyniku strace.
Więcej informacji powinno być dostępnych w:
źródło
strace wyświetla wszystkie wywołania systemowe wykonane przez proces, do którego jest zastosowany. Jeśli nie wiesz, co oznaczają wywołania systemowe, nie będziesz w stanie uzyskać z tego dużego przebiegu.
Niemniej jednak, jeśli twój problem dotyczy plików lub ścieżek lub wartości środowiska, uruchomienie śledzenia w problematycznym programie i przekierowanie danych wyjściowych do pliku, a następnie grepowanie tego pliku dla ciągu ścieżki / pliku / env może pomóc ci zobaczyć, co twój program naprawdę próbuje rób, w odróżnieniu od tego, czego się spodziewałeś.
źródło
strace <prog_name>
do śledzenia programu.strace -o <out_file> <prog_name>
strace -e open myprog
LUB dla wszystkich wywołań systemowych związanych z plikami:strace -e file myprog
Strace wyróżnia się jako narzędzie do badania systemów produkcyjnych, w których nie można sobie pozwolić na uruchomienie tych programów w trybie debuggera. W szczególności zastosowaliśmy strace w następujących dwóch sytuacjach:
Przykład analizy za pomocą strace znajduje się w mojej odpowiedzi na to pytanie .
źródło
Cały czas używam strace do debugowania problemów z uprawnieniami. Technika wygląda następująco:
Gdzie
gnome-calculator
jest polecenie, które chcesz uruchomić.źródło
strace -tfp PID będzie monitorował wywołania systemowe procesu PID, dzięki czemu możemy debugować / monitorować status naszego procesu / programu.
źródło
Strace może być używany jako narzędzie do debugowania lub jako prymitywny profiler.
Jako debugger możesz zobaczyć, jak dane wywołania systemowe były wywoływane, wykonywane i co zwracają. Jest to bardzo ważne, ponieważ pozwala zobaczyć nie tylko, że program się nie powiódł, ale DLACZEGO program się nie powiódł. Zwykle wynika to z kiepskiego kodowania, które nie uchwyciło wszystkich możliwych wyników programu. Innym razem są to po prostu zakodowane ścieżki do plików. Bez strachu możesz zgadnąć, co poszło nie tak, gdzie i jak. Dzięki strace otrzymujesz awarię wywołania systemowego, zwykle samo spojrzenie na wartość zwracaną wiele mówi.
Profilowanie to kolejne zastosowanie. Możesz go użyć do wykonania każdego połączenia systemowego osobno lub jako agregację. Chociaż może to nie wystarczyć do rozwiązania problemów, przynajmniej znacznie zawęzi listę potencjalnych podejrzanych. Jeśli widzisz wiele par fopen / close w jednym pliku, prawdopodobnie niepotrzebnie otwierasz i zamykasz pliki przy każdym wykonaniu pętli, zamiast otwierać i zamykać ją poza pętlą.
Ltrace jest bliskim kuzynem Strace'a, również bardzo przydatnym. Musisz nauczyć się odróżniać, gdzie jest twoje wąskie gardło. Jeśli całkowite wykonanie wynosi 8 sekund, a Ty spędzasz tylko 0,05 sekundy na wywołaniach systemowych, wówczas uruchomienie programu nie przyniesie Ci wiele dobrego, problem tkwi w kodzie, co jest zwykle problemem logicznym, lub program faktycznie potrzebuje tak długo biegać.
Największym problemem ze strace / ltrace jest odczyt ich wyników. Jeśli nie wiesz, jak są wykonywane wywołania lub przynajmniej nazwy wywołań systemowych / funkcji, trudno będzie odczytać ich znaczenie. Wiedza na temat zwracanych funkcji może być również bardzo korzystna, szczególnie w przypadku różnych kodów błędów. Chociaż rozszyfrowanie jest uciążliwe, czasami naprawdę zwracają perłę wiedzy; kiedy zobaczyłem sytuację, w której skończyły mi się i-węzły, ale nie zabrakło wolnego miejsca, więc wszystkie zwykłe narzędzia nie dały mi żadnego ostrzeżenia, po prostu nie mogłem utworzyć nowego pliku. Odczytanie kodu błędu z wyjścia strace wskazało mi właściwy kierunek.
źródło
Strace to narzędzie, które informuje, w jaki sposób aplikacja współpracuje z systemem operacyjnym.
Odbywa się to poprzez informowanie o tym, jakie system operacyjny wywołuje twoja aplikacja i jakie parametry wywołuje.
Na przykład widzisz pliki, które program próbuje otworzyć, i niezależnie od tego, czy połączenie się powiedzie.
Za pomocą tego narzędzia można debugować różnego rodzaju problemy. Na przykład, jeśli aplikacja mówi, że nie może znaleźć biblioteki, o której wiesz, że masz zainstalowaną, strace powie ci, gdzie aplikacja szuka tego pliku.
A to tylko wierzchołek góry lodowej.
źródło
Strace jest dobrym narzędziem do nauki, w jaki sposób program wykonuje różne wywołania systemowe (żądania do jądra), a także raportuje te, które się nie powiodły, wraz z wartością błędu związaną z tym niepowodzeniem. Nie wszystkie awarie są błędami. Na przykład kod, który próbuje wyszukać plik, może otrzymać błąd ENOENT (brak takiego pliku lub katalogu), ale może to być dopuszczalny scenariusz w logice kodu.
Dobrym przykładem użycia strace jest debugowanie warunków wyścigu podczas tworzenia pliku tymczasowego. Na przykład program, który może tworzyć pliki przez dołączenie identyfikatora procesu (PID) do określonego łańcucha, może napotykać problemy w scenariuszach wielowątkowych. [PID + TID (identyfikator procesu + identyfikator wątku) lub lepsze wywołanie systemowe, takie jak mkstemp, naprawi to].
Jest także dobry do debugowania awarii. Może ci się przydać ten (mój) artykuł o awariach strace i debugowania .
źródło
Minimalny możliwy do uruchomienia przykład
Jeśli pojęcie nie jest jasne, istnieje prostszy przykład, którego nie widziałeś, który to wyjaśnia.
W tym przypadku przykładem jest niezależny zestaw Linux x86_64 (bez libc) hello world:
przywitania
GitHub w górę .
Złóż i uruchom:
Wyprowadza oczekiwane:
Teraz użyjmy strace na tym przykładzie:
Używamy:
env -i ASDF=qwer
do kontrolowania zmiennych środowiskowych: /unix/48994/how-to-run-a-program-in-a-clean-environment-in-bash-s999 -v
aby wyświetlić pełniejsze informacje w dziennikachstrace.log
teraz zawiera:Przy tak minimalnym przykładzie każdy znak wyjściowy jest oczywisty:
execve
wiersz: pokazuje sposóbstrace
wykonaniahello.out
, w tym argumenty CLI i środowisko, zgodnie z dokumentacją wman execve
write
linia: pokazuje wykonane przez nas wywołanie systemowe zapisu.6
jest długością łańcucha"hello\n"
.= 6
jest zwracaną wartością wywołania systemowego, która zgodnie z dokumentacjąman 2 write
jest liczbą zapisanych bajtów.exit
linia: pokazuje wykonane przez nas wywołanie systemowe wyjścia. Nie ma wartości zwracanej, ponieważ program został zamknięty!Bardziej złożone przykłady
Zastosowanie strace ma oczywiście na celu sprawdzenie, które wywołania systemowe faktycznie wykonują złożone programy, aby pomóc w debugowaniu / optymalizacji programu.
Warto zauważyć, że większość wywołań systemowych, które możesz napotkać w Linuksie, ma opakowania glibc, wiele z nich z POSIX .
Wewnętrznie owijki glibc używają mniej więcej takiego wbudowania: Jak wywołać wywołanie systemowe za pomocą sysenter w zestawie wbudowanym?
Następnym przykładem, który powinieneś przestudiować, jest POSIX
write
hello world:main.c
Skompiluj i uruchom:
Tym razem zobaczysz, że glibc wykonuje kilka wywołań systemowych,
main
aby skonfigurować ładne środowisko dla main.Wynika to z faktu, że nie używamy teraz programu wolnostojącego, ale bardziej popularnego programu glibc, który umożliwia funkcjonalność libc.
Następnie na każdym końcu
strace.log
zawiera:Dochodzimy zatem do wniosku, że
write
funkcja POSIX używa, niespodzianka !write
, wywołania systemowego Linux .Obserwujemy również, że
return 0
prowadzi to doexit_group
połączenia zamiastexit
. Ha, nie wiedziałem o tym! Właśnie dlategostrace
jest taki fajny.man exit_group
następnie wyjaśnia:A oto kolejny przykład, w którym badałem, które
dlopen
wykorzystuje wywołanie systemowe : /unix/226524/what-system-call-is-used-to-load-libraries-in-linux/462710#462710Testowane w Ubuntu 16.04, GCC 6.4.0, jądro Linuksa 4.4.0.
źródło
Oto kilka przykładów tego, jak używam strace do kopania na stronach internetowych. Mam nadzieję, że to jest pomocne.
Sprawdź czas do pierwszego bajtu:
Zobacz, jaki procent działań robi co. Wiele
lstat
ifstat
może to wskazywać, że nadszedł czas, aby wyczyścić pamięć podręczną:Wysyła a
trace.txt
, abyś mógł dokładnie zobaczyć, jakie połączenia są wykonywane.Użyj tego, aby sprawdzić, czy wszystko wziął między
.1
do.9
sekundy, aby załadować:Zobacz, jakie brakujące pliki lub katalogi złapały
strace
. Spowoduje to wygenerowanie wielu rzeczy związanych z naszym systemem - jedyne istotne bity dotyczą plików klienta:źródło
Podobały mi się niektóre odpowiedzi, w których czytane są informacje na
strace
temat interakcji z systemem operacyjnym.Właśnie to widzimy. System dzwoni. Jeśli porównasz,
strace
altrace
różnica jest bardziej oczywista.Z drugiej strony istnieje
ltrace
funkcja śledzenia.Chociaż kilkakrotnie sprawdzałem instrukcje, nie znalazłem źródła nazwy,
strace
ale jest to prawdopodobnie ślad wywołania systemowego, ponieważ jest to oczywiste.Istnieją trzy większe uwagi do powiedzenia
strace
.Uwaga 1: Obie te funkcje
strace
iltrace
są za pomocą wywołania systemowegoptrace
. Tak więcptrace
wywołanie systemowe działa skuteczniestrace
.Uwaga 2: Można używać różnych parametrów
strace
, ponieważstrace
mogą być bardzo szczegółowe. Lubię eksperymentować z-c
czym jest jak podsumowanie rzeczy. Na podstawie-c
możesz wybrać jedno wywołanie systemowe, tak jak-e trace=open
tam, gdzie zobaczysz tylko to połączenie. Może to być interesujące, jeśli sprawdzasz, jakie pliki zostaną otwarte podczas śledzenia polecenia. I oczywiście możesz użyć tegogrep
do tego samego celu, ale pamiętaj, że musisz przekierować w ten sposób,2>&1 | grep etc
aby zrozumieć, że pliki konfiguracyjne są przywoływane podczas wydawania polecenia.Uwaga 3: Uważam tę bardzo ważną notatkę. Nie jesteś ograniczony do konkretnej architektury.
strace
rozwali cię, ponieważ może śledzić pliki binarne różnych architektur.źródło