Menggunakan ftrace

ftrace adalah alat proses debug untuk memahami apa yang terjadi di dalam kernel Linux. Bagian berikut menjelaskan fungsi dasar ftrace, penggunaan ftrace dengan atrace (yang merekam peristiwa kernel), dan ftrace dinamis.

Untuk mengetahui detail tentang fungsi ftrace lanjutan yang tidak tersedia dari systrace, lihat dokumentasi ftrace di <kernel tree>/Documentation/trace/ftrace.txt.

Merekam peristiwa kernel dengan atrace

atrace (frameworks/native/cmds/atrace) menggunakan ftrace untuk merekam peristiwa kernel. Selanjutnya, systrace.py (atau run_systrace.py di versi Catapult yang lebih baru) menggunakan adb untuk menjalankan atrace di perangkat. atrace melakukan hal berikut:

  • Menyiapkan pelacakan mode pengguna dengan menetapkan properti (debug.atrace.tags.enableflags).
  • Mengaktifkan fungsi ftrace yang diinginkan dengan menulis ke node sysfs ftrace yang sesuai. Namun, karena ftrace mendukung lebih banyak fitur, Anda dapat menetapkan beberapa node sysfs sendiri, lalu menggunakan atrace.

Dengan pengecualian pelacakan waktu booting, andalkan penggunaan atrace untuk menetapkan properti ke nilai yang sesuai. Properti ini adalah bitmask dan tidak ada cara yang baik untuk menentukan nilai yang benar selain melihat header yang sesuai (yang dapat berubah di antara rilis Android).

Mengaktifkan peristiwa ftrace

Node sysfs ftrace berada di /sys/kernel/tracing dan peristiwa trace dibagi menjadi beberapa kategori di /sys/kernel/tracing/events.

Untuk mengaktifkan peristiwa per kategori, gunakan:

echo 1 > /sys/kernel/tracing/events/irq/enable

Untuk mengaktifkan peristiwa per peristiwa, gunakan:

echo 1 > /sys/kernel/tracing/events/sched/sched_wakeup/enable

Jika peristiwa tambahan telah diaktifkan dengan menulis ke node sysfs, peristiwa tersebut tidak akan direset oleh atrace. Pola umum untuk pengaktifan perangkat Qualcomm adalah mengaktifkan tracepoint kgsl (GPU) dan mdss (pipeline tampilan), lalu menggunakan atrace atau 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

Anda juga dapat menggunakan ftrace tanpa atrace atau systrace, yang berguna jika Anda menginginkan rekaman aktivitas khusus kernel (atau jika Anda telah meluangkan waktu untuk menulis properti pelacakan mode pengguna secara manual). Untuk menjalankan ftrace saja:

  1. Tetapkan ukuran buffer ke nilai yang cukup besar untuk rekaman aktivitas Anda:
    echo 96000 > /sys/kernel/tracing/buffer_size_kb
    
  2. Aktifkan pelacakan:
    echo 1 > /sys/kernel/tracing/tracing_on
    
  3. Jalankan pengujian, lalu nonaktifkan pelacakan:
    echo 0 > /sys/kernel/tracing/tracing_on
    
  4. Dump aktivitas:
    cat /sys/kernel/tracing/trace > /data/local/tmp/trace_output
    

trace_output memberikan rekaman aktivitas dalam bentuk teks. Untuk memvisualisasinya menggunakan Catapult, dapatkan repositori Catapult dari GitHub dan jalankan trace2html:

catapult/tracing/bin/trace2html ~/path/to/trace_file

Secara default, tindakan ini akan menulis trace_file.html di direktori yang sama.

Menghubungkan peristiwa

Sering kali berguna untuk melihat visualisasi Catapult dan log ftrace secara bersamaan; misalnya, beberapa peristiwa ftrace (terutama yang khusus vendor) tidak divisualisasikan oleh Catapult. Namun, stempel waktu Catapult bersifat relatif terhadap peristiwa pertama dalam rekaman aktivitas atau stempel waktu tertentu yang di-dump oleh atrace, sedangkan stempel waktu ftrace mentah didasarkan pada sumber clock absolut tertentu di kernel Linux.

Untuk menemukan peristiwa ftrace tertentu dari peristiwa Catapult:

  1. Buka log ftrace mentah. Trace dalam versi terbaru systrace dikompresi secara default:
    • Jika Anda mengambil systrace dengan --no-compress, file ini ada dalam file html di bagian yang dimulai dengan BEGIN TRACE.
    • Jika tidak, jalankan html2trace dari hierarki Catapult (tracing/bin/html2trace) untuk mengekstrak kompresi rekaman aktivitas.
  2. Temukan stempel waktu relatif dalam visualisasi Catapult.
  3. Temukan baris di awal rekaman aktivitas yang berisi tracing_mark_sync. Ini akan terlihat seperti berikut:
    <5134>-5134  (-----) [003] ...1    68.104349: tracing_mark_write: trace_event_clock_sync: parent_ts=68.104286
    

    Jika baris ini tidak ada (atau jika Anda menggunakan ftrace tanpa atrace), maka waktu akan bersifat relatif dari peristiwa pertama dalam log ftrace.
    1. Tambahkan stempel waktu relatif (dalam milidetik) ke nilai di parent_ts (dalam detik).
    2. Telusuri stempel waktu baru.

Langkah-langkah ini akan menempatkan Anda di (atau setidaknya sangat dekat dengan) peristiwa.

Menggunakan ftrace dinamis

Jika systrace dan ftrace standar tidak memadai, ada satu upaya terakhir yang tersedia: ftrace dinamis. Ftrace dinamis melibatkan penulisan ulang kode kernel setelah booting, dan sebagai hasilnya, ftrace dinamis tidak tersedia di kernel produksi karena alasan keamanan. Namun, setiap bug performa yang sulit di tahun 2015 dan 2016 pada akhirnya disebabkan oleh akar masalah menggunakan ftrace dinamis. Hal ini sangat efektif untuk men-debug tidur yang tidak dapat diganggu karena Anda bisa mendapatkan pelacakan tumpukan di kernel setiap kali Anda menekan fungsi yang memicu tidur yang tidak dapat diganggu. Anda juga dapat men-debug bagian dengan interupsi dan preemptif dinonaktifkan, yang dapat sangat berguna untuk membuktikan masalah.

Untuk mengaktifkan ftrace dinamis, edit defconfig kernel Anda:

  1. Hapus CONFIG_STRICT_MEMORY_RWX (jika ada). Jika Anda menggunakan 3.18 atau yang lebih baru dan arm64, opsi ini tidak akan ada.
  2. Tambahkan hal berikut: CONFIG_DYNAMIC_FTRACE=y, CONFIG_FUNCTION_TRACER=y, CONFIG_IRQSOFF_TRACER=y, CONFIG_FUNCTION_PROFILER=y, dan CONFIG_PREEMPT_TRACER=y
  3. Build ulang dan booting kernel baru.
  4. Jalankan kode berikut untuk memeriksa pelacak yang tersedia:
    cat /sys/kernel/tracing/available_tracers
    
  5. Pastikan perintah menampilkan function, irqsoff, preemptoff, dan preemptirqsoff.
  6. Jalankan perintah berikut untuk memastikan ftrace dinamis berfungsi:
    cat /sys/kernel/tracing/available_filter_functions | grep <a function you care about>
    

Setelah menyelesaikan langkah-langkah ini, Anda memiliki ftrace dinamis, profiler fungsi, profiler irqsoff, dan profiler preemptoff yang tersedia. Kami sangat menyarankan untuk membaca dokumentasi ftrace tentang topik ini sebelum menggunakannya karena sangat canggih tetapi kompleks. irqsoff dan preemptoff terutama berguna untuk mengonfirmasi bahwa driver mungkin membiarkan interupsi atau preemption dinonaktifkan terlalu lama.

Profiler fungsi adalah opsi terbaik untuk masalah performa dan sering kali digunakan untuk mengetahui tempat fungsi dipanggil.


Jika data dari profiler fungsi tidak cukup spesifik, Anda dapat menggabungkan tracepoint ftrace dengan profiler fungsi. Peristiwa ftrace dapat diaktifkan dengan cara yang sama persis seperti biasa, dan peristiwa tersebut akan diselingi dengan rekaman aktivitas Anda. Hal ini sangat bagus jika ada tidur panjang yang tidak dapat diganggu sesekali dalam fungsi tertentu yang ingin Anda debug: tetapkan filter ftrace ke fungsi yang Anda inginkan, aktifkan tracepoint, ambil rekaman aktivitas. Anda dapat mengurai trace yang dihasilkan dengan trace2html, menemukan peristiwa yang diinginkan, lalu mendapatkan stack trace terdekat dalam trace mentah.

Menggunakan lockstat

Terkadang, ftrace tidak cukup dan Anda benar-benar perlu men-debug apa yang tampaknya merupakan pertentangan kunci kernel. Ada satu opsi kernel lagi yang patut dicoba: CONFIG_LOCK_STAT. Ini adalah upaya terakhir karena sangat sulit untuk berfungsi di perangkat Android karena meng-inflate ukuran kernel di luar kemampuan sebagian besar perangkat.

Namun, lockstat menggunakan infrastruktur penguncian debug, yang berguna untuk banyak aplikasi lainnya. Semua orang yang menangani penyiapan perangkat harus mencari cara agar opsi tersebut berfungsi di setiap perangkat karena akan ada saatnya Anda berpikir "Seandainya saya dapat mengaktifkan LOCK_STAT, saya dapat mengonfirmasi atau menyangkal hal ini sebagai masalah dalam lima menit, bukan lima hari".


Jika Anda dapat mem-booting kernel dengan opsi konfigurasi, pelacakan kunci mirip dengan ftrace:

  1. Aktifkan pelacakan:
    echo 1 > /proc/sys/kernel/lock_stat
    
  2. Jalankan pengujian Anda.
  3. Menonaktifkan pelacakan:
    echo 0 > /proc/sys/kernel/lock_stat
    
  4. Buat dump aktivitas:
    cat /proc/lock_stat > /data/local/tmp/lock_stat
    

Untuk mendapatkan bantuan dalam menafsirkan output yang dihasilkan, lihat dokumentasi lockstat di <kernel>/Documentation/locking/lockstat.txt.

Menggunakan tracepoint vendor

Gunakan tracepoint upstream terlebih dahulu, tetapi terkadang Anda perlu menggunakan tracepoint vendor:

  { "gfx",        "Graphics",         ATRACE_TAG_GRAPHICS, {
        { OPT,      "events/mdss/enable" },
        { OPT,      "events/sde/enable" },
        { OPT,      "events/mali_systrace/enable" },
    } },

Tracepoint dapat diperluas oleh layanan HAL yang memungkinkan Anda menambahkan titik/kategori trace khusus perangkat. Tracepoint terintegrasi dengan aplikasi pelacakan sistem di perangkat, atrace/systrace, dan perfetto.

API untuk menerapkan tracepoint/kategori adalah:

  • listCategories() menghasilkan (vec<TracingCategory> categories);
  • enableCategories(vec<string> categories) menghasilkan (Status status);
  • disableAllCategories() menghasilkan (Status status);
Untuk informasi lebih lanjut, lihat definisi HAL dan penerapan default di AOSP: