ftrace'i kullanma

ftrace, Linux çekirdeğinin içinde neler olduğunu anlamak için kullanılan bir hata ayıklama aracıdır. Aşağıdaki bölümlerde temel ftrace işlevi, atrace ile ftrace kullanımı (çekirdek etkinliklerini yakalar) ve dinamik ftrace ayrıntılı olarak açıklanmıştır.

systrace'te kullanılamayan gelişmiş ftrace işlevleri hakkında ayrıntılı bilgi için <kernel tree>/Documentation/trace/ftrace.txt adresindeki ftrace dokümanlarına bakın.

atrace ile çekirdek etkinliklerini yakalama

atrace (frameworks/native/cmds/atrace), çekirdek etkinliklerini yakalamak için ftrace'i kullanır. systrace.py (veya Catapult'ın sonraki sürümlerinde run_systrace.py) ise cihazda atrace çalıştırmak için adb'yi kullanır. atrace aşağıdakileri yapar:

  • Bir özellik (debug.atrace.tags.enableflags) ayarlayarak kullanıcı modunda izlemeyi ayarlar.
  • Uygun ftrace sysfs düğümlerine yazarak istenen ftrace işlevini etkinleştirir. Ancak ftrace daha fazla özelliği desteklediğinden bazı sysfs düğümlerini kendiniz ayarlayabilir ve ardından atrace'i kullanabilirsiniz.

Atrace'i kullanarak özelliği uygun değere ayarlamak için önyükleme zamanı izleme hariç. Özellik bir bit maskesi olduğundan doğru değerleri belirlemenin uygun başlığa bakmaktan (Android sürümleri arasında değişebilir) başka iyi bir yolu yoktur.

ftrace etkinliklerini etkinleştirme

ftrace sysfs düğümleri /sys/kernel/tracing içindedir ve trace etkinlikleri /sys/kernel/tracing/events içinde kategorilere ayrılır.

Etkinlikleri kategori bazında etkinleştirmek için:

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

Etkinlikleri etkinlik bazında etkinleştirmek için şunları kullanın:

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

sysfs düğümlerine yazarak etkinleştirilen ek etkinlikler, atrace tarafından sıfırlanmaz. Qualcomm cihazı başlatmak için yaygın olarak kullanılan bir yöntem, kgsl (GPU) ve mdss (görüntü ardışık düzeni) izleme noktalarını etkinleştirip ardından atrace veya systrace kullanmaktır:

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

ftrace'i atrace veya systrace olmadan da kullanabilirsiniz. Bu, yalnızca çekirdek izlemeleri istediğinizde (veya kullanıcı modu izleme özelliğini manuel olarak yazmak için zaman ayırdıysanız) kullanışlıdır. Yalnızca ftrace'i çalıştırmak için:

  1. Arabellek boyutunu, izlemeniz için yeterince büyük bir değere ayarlayın:
    echo 96000 > /sys/kernel/tracing/buffer_size_kb
    
  2. İzlemeyi etkinleştirme:
    echo 1 > /sys/kernel/tracing/tracing_on
    
  3. Testinizi çalıştırın, ardından izlemeyi devre dışı bırakın:
    echo 0 > /sys/kernel/tracing/tracing_on
    
  4. İzlemeyi dökme:
    cat /sys/kernel/tracing/trace > /data/local/tmp/trace_output
    

trace_output, izlemeyi metin biçiminde verir. Catapult'ı kullanarak görselleştirmek için GitHub'dan Catapult deposunu indirin ve trace2html'i çalıştırın:

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

Bu işlem varsayılan olarak trace_file.html dosyasını aynı dizine yazar.

Etkinlikleri ilişkilendirme

Catapult görselleştirmesine ve ftrace günlüğüne aynı anda bakmak genellikle yararlıdır. Örneğin, bazı ftrace etkinlikleri (özellikle tedarikçiye özgü olanlar) Catapult tarafından görselleştirilmez. Ancak Catapult'ın zaman damgaları, izlemedeki ilk etkinliğe veya atrace tarafından dökümü alınan belirli bir zaman damgasına göredir. Ham ftrace zaman damgaları ise Linux çekirdeğinde belirli bir mutlak saat kaynağına dayanır.

Bir Catapult etkinliğindeki belirli bir ftrace etkinliğini bulmak için:

  1. Ham ftrace günlüğünü açın. systrace'in son sürümlerindeki izler varsayılan olarak sıkıştırılır:
    • Systrace'inizi --no-compress ile yakaladıysanız bu, html dosyasında BEGIN TRACE ile başlayan bölümde bulunur.
    • Aksi takdirde, izlemenin sıkıştırmasını açmak için Catapult ağacından (tracing/bin/html2trace) html2trace'i çalıştırın.
  2. Catapult görselleştirmesinde göreli zaman damgasını bulun.
  3. İzlemenin başında tracing_mark_sync içeren bir satır bulun. Bu, aşağıdaki gibi görünmelidir:
    <5134>-5134  (-----) [003] ...1    68.104349: tracing_mark_write: trace_event_clock_sync: parent_ts=68.104286
    

    Bu satır mevcut değilse (veya ftrace'i atrace olmadan kullandıysanız) zamanlamalar, ftrace günlüklerindeki ilk etkinliğe göre olur.
    1. Göreli zaman damgasını (milisaniye cinsinden) parent_ts alanındaki değere (saniye cinsinden) ekleyin.
    2. Yeni zaman damgasını arayın.

Bu adımlar sayesinde etkinliğe (veya en azından etkinliğe çok yakın bir yere) ulaşabilirsiniz.

Dinamik ftrace kullanma

systrace ve standart ftrace yeterli olmadığında son bir çare daha vardır: dinamik ftrace. Dinamik ftrace, önyükleme işleminden sonra çekirdek kodunun yeniden yazılmasını içerir. Bu nedenle, güvenlik nedeniyle üretim çekirdeklerinde kullanılamaz. Ancak 2015 ve 2016'daki her zorlu performans hatasının kök nedeni, dinamik ftrace kullanılarak bulunmuştur. Kesintiye uğramayan uyku modunu tetikleyen işleve her bastığınızda çekirdekte bir yığın izlemesi alabileceğiniz için özellikle kesintisiz uyku modunda hata ayıklama için güçlüdür. Ayrıca, kesintileri ve öncelikli kesintileri devre dışı bırakarak bölümlerde hata ayıklama yapabilirsiniz. Bu, sorunları kanıtlamak için çok yararlı olabilir.

Dinamik ftrace'i etkinleştirmek için çekirdeğinizin defconfig dosyasını düzenleyin:

  1. CONFIG_STRICT_MEMORY_RWX (varsa) kaldırılmalıdır. 3.18 veya daha yeni bir sürüm kullanıyorsanız ve arm64 kullanıyorsanız bu seçenek yoktur.
  2. Aşağıdakileri ekleyin: CONFIG_DYNAMIC_FTRACE=y, CONFIG_FUNCTION_TRACER=y, CONFIG_IRQSOFF_TRACER=y, CONFIG_FUNCTION_PROFILER=y ve CONFIG_PREEMPT_TRACER=y
  3. Yeni çekirdeği yeniden oluşturup önyükleyin.
  4. Mevcut izleyicileri kontrol etmek için aşağıdakileri çalıştırın:
    cat /sys/kernel/tracing/available_tracers
    
  5. Komutun function, irqsoff, preemptoff ve preemptirqsoff döndürdüğünü onaylayın.
  6. Dinamik ftrace'in çalıştığından emin olmak için aşağıdakileri çalıştırın:
    cat /sys/kernel/tracing/available_filter_functions | grep <a function you care about>
    

Bu adımları tamamladıktan sonra dinamik ftrace, işlev profilleyici, irqsoff profilleyici ve preemptoff profilleyiciyi kullanabilirsiniz. Güçlü ancak karmaşık oldukları için bu konuları kullanmadan önce bu konularla ilgili ftrace belgelerini okumanızı önemle tavsiye ederiz. irqsoff ve preemptoff, öncelikle sürücülerin kesintileri veya önceliği çok uzun süre kapalı bırakabileceğini doğrulamak için yararlıdır.

Performans sorunları için en iyi seçenek olan işlev profilleyici, genellikle bir işlevin nerede çağrıldığını bulmak için kullanılır.


İşlev profilleyiciden alınan veriler yeterince spesifik değilse ftrace izleme noktalarını işlev profilleyiciyle birleştirebilirsiniz. ftrace etkinlikleri, her zamanki gibi etkinleştirilebilir ve izlemenizle birlikte yerleştirilir. Hata ayıklama yapmak istediğiniz belirli bir işlevde zaman zaman kesintisiz uzun bir uyku varsa bu yöntemi kullanabilirsiniz: ftrace filtresini istediğiniz işleve ayarlayın, izleme noktalarını etkinleştirin, izleme yapın. Elde edilen izlemeyi trace2html ile ayrıştırabilir, istediğiniz etkinliği bulabilir ve ardından ham izlemede yakındaki yığın izlemelerini alabilirsiniz.

lockstat'i kullanma

Bazen ftrace yeterli olmaz ve çekirdek kilidi anlaşmazlığı gibi görünen bir sorunda gerçekten hata ayıklama yapmanız gerekir. Denemeye değer başka bir çekirdek seçeneği daha vardır: CONFIG_LOCK_STAT. Android cihazlarda çalışmasını sağlamak son derece zor olduğu için bu yöntem son çare olarak kullanılır. Bunun nedeni, çekirdeğin boyutunu çoğu cihazın kaldırabileceğinden daha fazla şişirmesidir.

Ancak lockstat, diğer birçok uygulama için yararlı olan hata ayıklama kilitleme altyapısını kullanır. Cihazları kullanıma sunma konusunda çalışan herkesin, bu seçeneği her cihazda çalıştırmanın bir yolunu bulması gerekir. Çünkü "Keşke LOCK_STAT'yi açabilsem de bu sorunu beş gün yerine beş dakikada doğrulayabilsem veya redd edebilsem" diye düşüneceğiniz bir zaman gelecek.


Bir çekirdeği config seçeneğiyle önyükleyebiliyorsanız kilit izleme, ftrace'e benzer:

  1. İzlemeyi etkinleştirme:
    echo 1 > /proc/sys/kernel/lock_stat
    
  2. Testinizi çalıştırın.
  3. İzlemeyi devre dışı bırakma:
    echo 0 > /proc/sys/kernel/lock_stat
    
  4. İzlemenizi dökme:
    cat /proc/lock_stat > /data/local/tmp/lock_stat
    

Elde edilen çıkışı yorumlama konusunda yardım için <kernel>/Documentation/locking/lockstat.txt adresindeki lockstat dokümanlarına bakın.

Tedarikçi firma izleme noktalarını kullanma

Öncelikle yayın öncesi izleme noktalarını kullanın ancak bazen tedarikçi firma izleme noktalarını kullanmanız gerekir:

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

İzleme noktaları, HAL hizmeti tarafından genişletilebilir. Bu sayede cihaza özel izleme noktaları/kategoriler ekleyebilirsiniz. İzleme noktaları, perfetto, atrace/systrace ve cihaz üzerinde sistem izleme uygulamasıyla entegredir.

İzleme noktalarını/kategorileri uygulamak için kullanılan API'ler şunlardır:

  • listCategories(), (vec<TracingCategory> categories) değerini döndürür.
  • enableCategories(vec<string> categories) (Status status) değerini döndürür;
  • disableAllCategories() (Durum durumu) oluşturur;
Daha fazla bilgi için AOSP'deki HAL tanımına ve varsayılan uygulamaya bakın: