ftrace to narzędzie do debugowania, które pozwala zrozumieć, co dzieje się w rdzeniu systemu Linux. W poniższych sekcjach opisano podstawowe funkcje ftrace, użycie ftrace z atrace (który rejestruje zdarzenia jądra) oraz dynamiczne ftrace.
Szczegółowe informacje o zaawansowanych funkcjach ftrace, które nie są dostępne w systrace, znajdziesz w dokumentacji ftrace na stronie <kernel
tree>/Documentation/trace/ftrace.txt
.
Rejestrowanie zdarzeń jądra za pomocą atrace
atrace (frameworks/native/cmds/atrace
) używa narzędzia ftrace do rejestrowania zdarzeń jądra. Z kolei systrace.py (lub run_systrace.py w późniejszych wersjach Catapult) używa adb do uruchamiania atrace na urządzeniu. atrace wykonuje te czynności:
- Konfiguruje śledzenie w trybie użytkownika, ustawiając właściwość (
debug.atrace.tags.enableflags
). - Umożliwia wybraną funkcję ftrace przez zapisywanie danych w odpowiednich węzłach sysfs ftrace. Ponieważ jednak ftrace obsługuje więcej funkcji, możesz samodzielnie skonfigurować niektóre węzły sysfs, a potem użyć atrace.
Z wyjątkiem śledzenia w czasie uruchamiania używaj narzędzia atrace do ustawiania właściwości na odpowiednią wartość. Właściwość jest maską bitową i nie ma dobrego sposobu na określenie prawidłowych wartości, oprócz sprawdzenia odpowiedniego nagłówka (który może się zmieniać w różnych wersjach Androida).
Włączanie zdarzeń ftrace
Węzły sysfs ftrace znajdują się w katalogu /sys/kernel/tracing
, a zdarzenia śledzone są podzielone na kategorie w katalogu /sys/kernel/tracing/events
.
Aby włączyć zdarzenia według kategorii, użyj:
echo 1 > /sys/kernel/tracing/events/irq/enable
Aby włączyć zdarzenia na podstawie poszczególnych zdarzeń, użyj:
echo 1 > /sys/kernel/tracing/events/sched/sched_wakeup/enable
Jeśli dodatkowe zdarzenia zostały włączone przez zapisanie w węzłach sysfs, nie zostaną zresetowane przez atrace. Typowym sposobem wdrażania urządzenia Qualcomm jest włączenie punktów śledzenia kgsl
(GPU) i mdss
(rury wyświetlania), a następnie użycie atrace lub systrace:
adb shell "echo 1 > /sys/kernel/tracing/events/mdss/enable"
adb shell "echo 1 > /sys/kernel/tracing/events/kgsl/enable"
./systrace.py sched freq idle am wm gfx view binder_driver irq workq ss sync -t 10 -b 96000 -o full_trace.html
Możesz też używać ftrace bez atrace lub systrace, co jest przydatne, gdy chcesz uzyskać śledzenie tylko w jądrze (lub jeśli poświęcisz czas na ręczne napisanie właściwości śledzenia w trybie użytkownika). Aby uruchomić tylko narzędzie ftrace:
- Ustaw rozmiar bufora na wartość wystarczająco dużą dla Twojego śledzenia:
echo 96000 > /sys/kernel/tracing/buffer_size_kb
- Włączanie śledzenia:
echo 1 > /sys/kernel/tracing/tracing_on
- Przeprowadź test, a potem wyłącz śledzenie:
echo 0 > /sys/kernel/tracing/tracing_on
- Wyświetlanie zrzutu:
cat /sys/kernel/tracing/trace > /data/local/tmp/trace_output
Parametr trace_output zwraca ślad w postaci tekstu. Aby zwizualizować go za pomocą Catapult, pobierz repozytorium Catapult z GitHuba i uruchom trace2html:
catapult/tracing/bin/trace2html ~/path/to/trace_file
Domyślnie plik trace_file.html
jest zapisywany w tym samym katalogu.
Powiązanie zdarzeń
Często warto spojrzeć na wizualizację w Catapult i na dziennik ftrace jednocześnie. Na przykład niektóre zdarzenia ftrace (zwłaszcza te związane z konkretnym dostawcą) nie są wizualizowane przez Catapult. Jednak sygnatury czasowe Catapult są względne względem pierwszego zdarzenia w śladzie lub określonej sygnatury czasowej zdumpowanej przez atrace, podczas gdy surowe sygnatury czasowe ftrace są oparte na określonym źródło czasu bezwzględnego w rdzeniu systemu Linux.
Aby znaleźć określone zdarzenie ftrace z wydarzenia Catapult:
- Otwórz nieprzetworzony dziennik ftrace. Ścieżki w najnowszych wersjach narzędzia systrace są domyślnie kompresowane:
- Jeśli dane systrace zostały zebrane za pomocą narzędzia
--no-compress
, znajdują się one w pliku HTML w sekcji zaczynającej się od BEGIN TRACE. - Jeśli nie, uruchom html2trace z drzewa Catapult (
tracing/bin/html2trace
), aby rozpakować ślad.
- Jeśli dane systrace zostały zebrane za pomocą narzędzia
- Znajdź względną sygnaturę czasową w wizualizacji Catapult.
- Znajdź wiersz na początku ścieżki zawierający
tracing_mark_sync
. Powinien on wyglądać mniej więcej tak:<5134>-5134 (-----) [003] ...1 68.104349: tracing_mark_write: trace_event_clock_sync: parent_ts=68.104286
Jeśli ta linia nie istnieje (lub jeśli używasz ftrace bez atrace), czasy będą względne do pierwszego zdarzenia w logu ftrace.- Dodaj względną sygnaturę czasową (w milisekundach) do wartości w polu
parent_ts
(w sekundach). - Wyszukaj nowy sygnaturę czasową.
- Dodaj względną sygnaturę czasową (w milisekundach) do wartości w polu
Dzięki tym czynnościom możesz dotrzeć do miejsca wydarzenia (lub przynajmniej bardzo się do niego zbliżyć).
Używanie dynamicznego narzędzia ftrace
Jeśli nie wystarczają Ci informacje z systrace i standardowego narzędzia ftrace, możesz skorzystać z jednego z tych ostatnich rozwiązań: dynamic ftrace. Dynamiczne ftrace wymaga przepisania kodu jądra po uruchomieniu, dlatego ze względów bezpieczeństwa nie jest dostępne w jądrach produkcyjnych. Jednak każdy pojedynczy trudny błąd związany z wydajnością w latach 2015 i 2016 miał w końcu przyczynę pierwotną, którą udało się znaleźć za pomocą dynamicznego ftrace. Jest to szczególnie przydatne podczas debugowania nieprzerwanych okresów uśpienia, ponieważ za każdym razem, gdy wywołasz funkcję wywołującą nieprzerwany okres uśpienia, możesz uzyskać ślad stosu w rdzeniu. Możesz też debugować sekcje z wyłączonymi przerwaniami i wyprzedzeniami, co może być bardzo przydatne do potwierdzenia problemów.
Aby włączyć dynamiczne ftrace, edytuj plik defconfig jądra:
- Usuń CONFIG_STRICT_MEMORY_RWX (jeśli jest obecny). Jeśli używasz wersji 3.18 lub nowszej i procesora ARM64, nie będzie ona dostępna.
- Dodaj te opcje: CONFIG_DYNAMIC_FTRACE=y, CONFIG_FUNCTION_TRACER=y, CONFIG_IRQSOFF_TRACER=y, CONFIG_FUNCTION_PROFILER=y i CONFIG_PREEMPT_TRACER=y.
- Utwórz nowe jądro i uruchom je.
- Aby sprawdzić, czy są dostępne lokalizatory, wykonaj te czynności:
cat /sys/kernel/tracing/available_tracers
- Sprawdź, czy polecenie zwraca wartości
function
,irqsoff
,preemptoff
ipreemptirqsoff
. - Aby sprawdzić, czy dynamiczna funkcja ftrace działa, wykonaj te czynności:
cat /sys/kernel/tracing/available_filter_functions | grep <a function you care about>
Po wykonaniu tych czynności masz dostępne dynamiczne narzędzie ftrace, profilujący funkcje, narzędzie irqsoff i preemptoff. Przed użyciem tych poleceń zdecydowanie zalecamy zapoznanie się z dokumentacją ftrace na ten temat, ponieważ są one bardzo wydajne, ale skomplikowane. Polecenia irqsoff i preemptoff są przydatne głównie do sprawdzania, czy sterowniki mogą zbyt długo pozostawiać przerwania lub wymuszanie wyłączone.
Profilator funkcji to najlepsze narzędzie do wykrywania problemów z wydajnością. Często służy do sprawdzania, gdzie jest wywoływana funkcja.
Jeśli dane z profilowania funkcji nie są wystarczająco szczegółowe, możesz połączyć punkty śledzenia ftrace z profilowaniem funkcji. Zdarzenia ftrace można włączyć w taki sam sposób jak zwykle, a będą one przeplatane ze śledzeniem.
To świetne rozwiązanie, jeśli w konkretnej funkcji, którą chcesz debugować, występuje sporadyczny długi stan uśpienia bez możliwości przerwania: ustaw filtr ftrace na odpowiednią funkcję, włącz punkty śledzenia, wykonaj śledzenie. Możesz przeanalizować uzyskany ślad za pomocą funkcji trace2html
, znaleźć odpowiednie zdarzenie, a potem uzyskać z poziomu śladu pierwotnego dostępne ścieżki wywołań.
Korzystanie z lockstat
Czasami narzędzie ftrace nie wystarcza i trzeba debugować to, co wygląda na konflikt blokady jądra. Jest jeszcze jedna opcja jądra, którą warto wypróbować:
CONFIG_LOCK_STAT
. Jest to ostateczność, ponieważ bardzo trudno jest uruchomić ją na urządzeniach z Androidem, ponieważ zwiększa rozmiar jądra ponad możliwości większości urządzeń.
Jednak lockstat korzysta z infrastruktury blokowania debugowania, która jest przydatna w wielu innych aplikacjach. Każda osoba pracująca nad prezentacją urządzenia powinna znaleźć sposób na włączenie tej opcji na każdym urządzeniu, ponieważ będzie czas, gdy pomyślisz: „Gdybym tylko mógł włączyć LOCK_STAT
, mógłbym potwierdzić lub zaprzeczyć, że to jest problem w ciągu 5 minut zamiast 5 dni”.
Jeśli możesz uruchomić jądro za pomocą opcji konfiguracji, śledzenie blokady działa podobnie jak ftrace:
- Włączanie śledzenia:
echo 1 > /proc/sys/kernel/lock_stat
- Przeprowadź test.
- Wyłączanie śledzenia:
echo 0 > /proc/sys/kernel/lock_stat
- Wyświetlanie danych z śledzenia:
cat /proc/lock_stat > /data/local/tmp/lock_stat
Aby dowiedzieć się, jak interpretować wynik, zapoznaj się z dokumentacją lockstat na stronie <kernel>/Documentation/locking/lockstat.txt
.
Korzystanie z punktów śledzenia dostawcy
Najpierw używaj punktów przekierowania na upstream, ale czasami musisz używać punktów dostawcy:
{ "gfx", "Graphics", ATRACE_TAG_GRAPHICS, { { OPT, "events/mdss/enable" }, { OPT, "events/sde/enable" }, { OPT, "events/mali_systrace/enable" }, } },
Punkty śledzenia można rozszerzać za pomocą usługi HAL, co pozwala dodawać punkty śledzenia/kategorie dotyczące konkretnych urządzeń. Punkty śledzenia są zintegrowane z perfetto, atrace/systrace i aplikacją do śledzenia systemu na urządzeniu.
Interfejsy API do implementowania punktów i kategorii śledzonych to:
- listCategories() generuje (vec<TracingCategory> categories);
- enableCategories(vec<string> categories) generuje (stan status);
- disableAllCategories() generuje (stan stanu);