Menggunakan ftrace

ftrace adalah alat debugging untuk memahami apa yang terjadi di dalam kernel Linux. Bagian berikut merinci fungsionalitas dasar ftrace, penggunaan ftrace dengan atrace (yang menangkap peristiwa kernel), dan ftrace dinamis.

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

Menangkap peristiwa kernel dengan atrace

atrace ( frameworks/native/cmds/atrace ) menggunakan ftrace untuk menangkap peristiwa kernel. Pada gilirannya, 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 menyetel properti ( debug.atrace.tags.enableflags ).
  • Mengaktifkan fungsionalitas ftrace yang diinginkan dengan menulis ke node ftrace sysfs yang sesuai. Namun, karena ftrace mendukung lebih banyak fitur, Anda dapat mengatur sendiri beberapa node sysfs kemudian menggunakan atrace.

Dengan pengecualian pelacakan waktu booting, andalkan penggunaan atrace untuk menyetel 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 acara ftrace

Node sysfs ftrace berada di /sys/kernel/tracing dan melacak peristiwa dibagi ke dalam kategori di /sys/kernel/tracing/events .

Untuk mengaktifkan acara per kategori, gunakan:

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

Untuk mengaktifkan acara berdasarkan per acara, gunakan:

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

Jika event tambahan telah diaktifkan dengan menulis ke sysfs node, event tersebut tidak akan direset oleh atrace. Pola umum untuk pengaktifan perangkat Qualcomm adalah mengaktifkan kgsl (GPU) dan mdss (pipa 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 saat Anda menginginkan pelacakan hanya kernel (atau jika Anda telah meluangkan waktu untuk menulis properti penelusuran mode pengguna dengan tangan). Untuk menjalankan hanya ftrace:

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

trace_output memberikan jejak dalam bentuk teks. Untuk memvisualisasikannya menggunakan Catapult, dapatkan repositori Catapult dari GitHub dan jalankan trace2html:

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

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

Peristiwa yang berhubungan

Seringkali berguna untuk melihat visualisasi Catapult dan log ftrace secara bersamaan; misalnya, beberapa acara ftrace (terutama yang khusus vendor) tidak divisualisasikan oleh Catapult. Namun, stempel waktu Catapult relatif terhadap peristiwa pertama dalam jejak atau stempel waktu tertentu yang dibuang oleh atrace, sedangkan stempel waktu ftrace mentah didasarkan pada sumber jam absolut tertentu di kernel Linux.

Untuk menemukan acara ftrace tertentu dari acara Catapult:

  1. Buka log ftrace mentah. Jejak dalam versi terbaru systrace dikompresi secara default:
    • Jika Anda menangkap systrace Anda dengan --no-compress , ini ada di file html di bagian yang dimulai dengan BEGIN TRACE.
    • Jika tidak, jalankan html2trace dari pohon Catapult ( tracing/bin/html2trace ) untuk membuka kompresi jejak.
  2. Temukan stempel waktu relatif dalam visualisasi Catapult.
  3. Temukan baris di awal jejak yang berisi tracing_mark_sync . Seharusnya terlihat seperti ini:
    <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 pengaturan waktu akan relatif dari peristiwa pertama di log ftrace.
    1. Tambahkan stempel waktu relatif (dalam milidetik) ke nilai dalam parent_ts (dalam detik).
    2. Cari stempel waktu baru.

Langkah-langkah ini harus menempatkan Anda di (atau setidaknya sangat dekat dengan) acara tersebut.

Menggunakan ftrace dinamis

Ketika systrace dan ftrace standar tidak mencukupi, ada satu jalan terakhir yang tersedia: dynamic ftrace . Ftrace dinamis melibatkan penulisan ulang kode kernel setelah boot, dan akibatnya kode tersebut tidak tersedia di kernel produksi karena alasan keamanan. Namun, setiap bug kinerja yang sulit pada tahun 2015 dan 2016 pada akhirnya disebabkan oleh akar menggunakan ftrace dinamis. Ini sangat kuat untuk men-debug tidur yang tidak pernah terputus karena Anda bisa mendapatkan jejak tumpukan di kernel setiap kali Anda menekan fungsi yang memicu tidur yang tidak pernah terputus. Anda juga dapat men-debug bagian dengan interupsi dan preemption dinonaktifkan, yang bisa 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 lebih baru dan arm64, itu tidak ada.
  2. Tambahkan berikut ini: CONFIG_DYNAMIC_FTRACE=y, CONFIG_FUNCTION_TRACER=y, CONFIG_IRQSOFF_TRACER=y, CONFIG_FUNCTION_PROFILER=y, dan CONFIG_PREEMPT_TRACER=y
  3. Bangun kembali dan boot kernel baru.
  4. Jalankan yang berikut ini untuk memeriksa pelacak yang tersedia:
    cat /sys/kernel/tracing/available_tracers
    
  5. Konfirmasikan function pengembalian perintah , irqsoff , preemptoff , dan preemptirqsoff .
  6. Jalankan yang berikut ini 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 kuat tetapi kompleks. irqsoff dan preemptoff terutama berguna untuk mengonfirmasi bahwa driver mungkin membiarkan interupsi atau preemptoff dimatikan terlalu lama.

Profiler fungsi adalah opsi terbaik untuk masalah kinerja dan sering digunakan untuk mencari tahu di mana suatu fungsi dipanggil.


Jika data dari profiler fungsi tidak cukup spesifik, Anda dapat menggabungkan titik jejak ftrace dengan profiler fungsi. acara ftrace dapat diaktifkan dengan cara yang persis sama seperti biasanya, dan mereka akan disisipkan dengan jejak Anda. Ini bagus jika ada waktu tidur lama yang tidak pernah terputus dalam fungsi tertentu yang ingin Anda debug: atur filter ftrace ke fungsi yang Anda inginkan, aktifkan tracepoints, ambil jejak. Anda dapat mengurai jejak yang dihasilkan dengan trace2html , menemukan acara yang Anda inginkan, lalu mendapatkan jejak tumpukan terdekat di jejak mentah.

Menggunakan lockstat

Kadang-kadang, ftrace tidak cukup dan Anda benar-benar perlu men-debug apa yang tampaknya merupakan pertentangan kunci kernel. Ada satu lagi opsi kernel yang patut dicoba: CONFIG_LOCK_STAT . Ini adalah upaya terakhir karena sangat sulit untuk bekerja di perangkat Android karena ukuran kernel membengkak melebihi apa yang dapat ditangani oleh sebagian besar perangkat.

Namun, lockstat menggunakan infrastruktur penguncian debug, yang berguna untuk banyak aplikasi lain. Semua orang yang bekerja di perangkat memunculkan harus mencari cara agar opsi itu berfungsi di setiap perangkat karena akan ada saatnya ketika Anda berpikir "Kalau saja saya bisa mengaktifkan LOCK_STAT , saya bisa mengonfirmasi atau membantah ini sebagai masalah dalam lima menit, bukan Lima hari."


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

  1. Aktifkan pelacakan:
    echo 1 > /proc/sys/kernel/lock_stat
    
  2. Jalankan tes Anda.
  3. Nonaktifkan pelacakan:
    echo 0 > /proc/sys/kernel/lock_stat
    
  4. Buang jejak Anda:
    cat /proc/lock_stat > /data/local/tmp/lock_stat
    

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

Menggunakan titik jejak vendor

Gunakan titik jejak hulu terlebih dahulu, tetapi terkadang Anda perlu menggunakan titik jejak vendor:

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

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

API untuk mengimplementasikan tracepoint/kategori adalah:

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