استخدام ftrace

ftrace هي أداة لتصحيح الأخطاء من أجل فهم ما يحدث داخل ملف ‎Linux kernel. توضِّح الأقسام التالية بالتفصيل الوظيفة الأساسية لواجهة ftrace واستخدام واجهة ftrace مع واجهة atrace (التي تسجِّل أحداث النواة) وواجهة ftrace الديناميكية.

للحصول على تفاصيل حول وظائف ftrace المتقدّمة غير المتوفّرة من systrace، يُرجى الرجوع إلى مستندات ftrace على الرابط <kernel tree>/Documentation/trace/ftrace.txt.

تسجيل أحداث kernel باستخدام atrace

تستخدِم أداة atrace ‏ (frameworks/native/cmds/atrace) أداة ftrace لتسجيل أحداث kernel. بدوره، يستخدم systrace.py (أو run_systrace.py في الإصدارات الأحدث من Catapult) أداة adb لتشغيل atrace على الجهاز. وتعمل أداة atrace على تنفيذ ما يلي:

  • لإعداد التتبُّع في وضع المستخدم، عليك ضبط خاصيّة (debug.atrace.tags.enableflags).
  • تفعيل وظيفة ftrace المطلوبة من خلال الكتابة في ملف sysfs المناسب لنظام ftrace ومع ذلك، بما أنّ ftrace تتيح المزيد من الميزات، يمكنك ضبط بعض عقد sysfs بنفسك ثم استخدام atrace.

باستثناء تتبُّع وقت التمهيد، يمكنك الاعتماد على استخدام atrace لضبط القيمة المناسبة على الخاصية. السمة هي قناع بتات ولا تتوفّر طريقة جيدة لتحديد القيم الصحيحة سوى الاطّلاع على العنوان المناسب (الذي قد يتغيّر بين إصدارات Android).

تفعيل أحداث ftrace

تقع عقد ftrace sysfs في /sys/kernel/tracing ويتم تقسيم أحداث trace إلى فئات في /sys/kernel/tracing/events.

لتفعيل الأحداث حسب الفئة، استخدِم:

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

لتفعيل الأحداث على أساس كل حدث، استخدِم:

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

إذا تم تفعيل أحداث إضافية من خلال الكتابة إلى عقد sysfs، لن تتم إعادة ضبطها بواسطة atrace. من الأنماط الشائعة لتشغيل أجهزة Qualcomm تفعيل نقاط التتبُّع kgsl (وحدة معالجة الرسومات) و mdss (مسار عرض) ثم استخدام atrace أو 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

يمكنك أيضًا استخدام ftrace بدون atrace أو systrace، وهو مفيد عندما تريد تتبُّع بيانات نظام التشغيل فقط (أو إذا كنت قد استغرقت بعض الوقت لكتابة خاصية تتبُّع وضع المستخدم يدويًا). لتشغيل ftrace فقط:

  1. اضبط حجم ذاكرة التخزين المؤقت على قيمة كبيرة بما يكفي لتتبُّع بياناتك:
    echo 96000 > /sys/kernel/tracing/buffer_size_kb
    
  2. تفعيل التتبّع:
    echo 1 > /sys/kernel/tracing/tracing_on
    
  3. أجرِ الاختبار، ثم أوقِف التتبُّع:
    echo 0 > /sys/kernel/tracing/tracing_on
    
  4. تفريغ التتبُّع:
    cat /sys/kernel/tracing/trace > /data/local/tmp/trace_output
    

يوفّر trace_output التتبّع في شكل نص. لعرضها باستخدام Catapult، يمكنك الحصول على مستودع Catapult من GitHub وتشغيل trace2html:

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

يتم تلقائيًا كتابة trace_file.html في الدليل نفسه.

ربط الأحداث

غالبًا ما يكون من المفيد الاطّلاع على الرسم البياني في Catapult وملف سجلّ ftrace في الوقت نفسه. على سبيل المثال، لا تعرض Catapult بعض أحداث ftrace (خاصةً تلك الخاصة بالمورّد ). ومع ذلك، تكون الطوابع الزمنية في Catapult نسبية إما إلى الحدث الأول في التتبُّع أو إلى طابع زمني محدّد تم تفريغه بواسطة atrace، في حين تستند الطوابع الزمنية الأولية لـ ftrace إلى مصدر مطلق معيّن للموقّت في نواة Linux.

للعثور على حدث ftrace معيّن من حدث Catapult:

  1. افتح سجلّ ftrace الأوّلي. يتم تلقائيًا ملفّات تتبُّع العمليات في الإصدارات الحديثة من systrace:
    • إذا سجّلت مسار تتبع النظام باستخدام --no-compress، يمكنك العثور عليه في ملف html في القسم الذي يبدأ بـ BEGIN TRACE.
    • إذا لم يكن الأمر كذلك، يمكنك تشغيل html2trace من ملف tracing/bin/html2trace في شجرة Catapult لفك ضغط عملية التتبّع.
  2. ابحث عن الطابع الزمني النسبي في الرسم البياني Catapult.
  3. ابحث عن سطر في بداية التتبُّع يحتوي على tracing_mark_sync. من المفترض أن يظهر العنصر على النحو التالي:
    <5134>-5134  (-----) [003] ...1    68.104349: tracing_mark_write: trace_event_clock_sync: parent_ts=68.104286
    

    إذا لم يكن هذا السطر متوفّرًا (أو إذا استخدمت ftrace بدون atrace)، ستكون المواعيد نسبية من أول حدث في سجلّ ftrace.
    1. أضِف الطابع الزمني النسبي (بالملي ثانية) إلى القيمة في parent_ts (بالثواني).
    2. ابحث عن الطابع الزمني الجديد.

من المفترض أن تؤدي هذه الخطوات إلى نقلك إلى مكان الحدث (أو على الأقل إلى مكان قريب جدًا منه).

استخدام أداة ftrace الديناميكية

عندما لا يكون systrace وftrace العاديان كافيين، يتوفّر تدبير آخر متاح: ftrace الديناميكي. تتضمن أداة ftrace الديناميكية إعادة كتابة رمز النواة بعد التشغيل، ونتيجةً لذلك، لا تتوفّر في أنظمة التشغيل النواة لأسباب تتعلق بالأمان. ومع ذلك، فإنّ كل خطأ صعب في الأداء في عامَي 2015 و2016 كان سببه الأساسي في النهاية استخدام أداة ftrace الديناميكية. وهو مفيد بشكلٍ خاص لتصحيح أخطاء حالات السكون غير القابلة للانقطاع لأنّه يمكنك الحصول على تتبع تسلسل استدعاء الدوال البرمجية في النواة في كل مرة تضغط فيها على الدالة التي تؤدي إلى حالة السكون غير القابلة للانقطاع. يمكنك أيضًا تصحيح أخطاء الأقسام التي تم إيقاف عمليات المقاطعة والاستبدال فيها، ما يمكن أن يكون مفعّلاً جدًا لإثبات المشاكل.

لتفعيل أداة ftrace الديناميكية، عدِّل ملف defconfig الخاص بالنواة:

  1. أزِل CONFIG_STRICT_MEMORY_RWX (إذا كان متوفّرًا). إذا كنت تستخدم الإصدار 3.18 أو إصدارًا أحدث وarm64، لن يكون متاحًا.
  2. أضِف ما يلي: CONFIG_DYNAMIC_FTRACE=y وCONFIG_FUNCTION_TRACER=y وCONFIG_IRQSOFF_TRACER=y وCONFIG_FUNCTION_PROFILER=y وCONFIG_PREEMPT_TRACER=y.
  3. أعِد إنشاء النواة الجديدة وشغِّلها.
  4. شغِّل ما يلي للتحقّق من المتتبّعين المتاحين:
    cat /sys/kernel/tracing/available_tracers
    
  5. تأكَّد من أنّ الأمر يعرض function وirqsoff preemptoff وpreemptirqsoff.
  6. شغِّل ما يلي للتأكّد من عمل أداة ftrace الديناميكية:
    cat /sys/kernel/tracing/available_filter_functions | grep <a function you care about>
    

بعد إكمال هذه الخطوات، ستتوفّر لك أداة ftrace الديناميكية ومحلل ملفّات تعريف الوظائف ومحلل irqsoff ومحلل preemptoff. ننصح بشدة بقراءة مستندات ftrace حول هذه المواضيع قبل استخدام هذه الأدوات لأنّها فعّالة ولكنّها معقّدة. إنّ irqsoff وpreemptoff مفيدين بشكل أساسي للتأكّد من أنّ برامج التشغيل قد تترك عمليات المقاطعة أو الاستبدال متوقفة لفترة طويلة جدًا.

إنّ أداة تحليل الأداء هي الخيار الأفضل لتحديد مشاكل الأداء، وغالبًا ما يتم استخدامها لتحديد مكان استدعاء دالة معيّنة.


إذا لم تكن البيانات الواردة من أداة تحليل الأداء الوظيفي دقيقة بما يكفي، يمكنك دمج نقاط تتبُّع أداة ftrace مع أداة تحليل الأداء الوظيفي. يمكن تفعيل أحداث أداة ftrace بالطريقة نفسها تمامًا كالمعتاد، وسيتم تداخلها مع عملية التتبُّع. هذه ميزة رائعة إذا كان هناك فترة نوم طويلة لا يمكن مقاطعتها في دالة معيّنة تريد تصحيح أخطاءها: اضبط فلتر ftrace على الدالة التي تريدها، فعِّل نقاط التتبُّع، ونفِّذ عملية تتبُّع. يمكنك تحليل التتبُّع الناتج باستخدام trace2html، والعثور على الحدث الذي تريده، ثم الحصول على عمليات تتبُّع تسلسل استدعاء الدوالّ المجاورة في التتبُّع الأوّلي.

استخدام lockstat

في بعض الأحيان، لا يكون ftrace كافيًا، وعليك تصحيح أخطاء ما يبدو أنّه تنافس على قفل kernel. هناك خيار آخر للنواة يستحق التجربة: CONFIG_LOCK_STAT. يُعدّ هذا الإجراء الملاذ الأخير، لأنّه من الصعوبة بمكان تشغيله على أجهزة Android لأنّه يضخّم حجم النواة إلى ما يتعذّر على معظم الأجهزة التعامل معه.

ومع ذلك، يستخدم lockstat بنية أساسية لعمليات إصلاح الأخطاء القفل، وهي مفيدة للعديد من التطبيقات الأخرى. على كل شخص يعمل على إعداد الجهاز أن يجد طريقة لتشغيل هذا الخيار على كل جهاز، لأنّه سيكون هناك وقت تعتقد فيه أنّه "لو كان بإمكاني تفعيل LOCK_STAT، كان بإمكاني تأكيد المشكلة أو دحضها في غضون خمس دقائق بدلاً من خمسة أيام".


إذا كان بإمكانك تشغيل نواة باستخدام خيار الإعداد، يكون تتبُّع القفل مشابهًا لمحاولة ftrace:

  1. تفعيل التتبّع:
    echo 1 > /proc/sys/kernel/lock_stat
    
  2. أجرِ الاختبار.
  3. إيقاف التتبّع:
    echo 0 > /proc/sys/kernel/lock_stat
    
  4. تفريغ التتبُّع:
    cat /proc/lock_stat > /data/local/tmp/lock_stat
    

للحصول على مساعدة في تفسير الإخراج الناتج، يُرجى الرجوع إلى مستندات lockstat على الرابط <kernel>/Documentation/locking/lockstat.txt.

استخدام نقاط تتبُّع المورّد

استخدِم نقاط التتبّع في المصدر أولاً، ولكن ستحتاج أحيانًا إلى استخدام نقاط التتبّع الخاصة بالمورّد:

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

يمكن توسيع نطاق نقاط التتبّع من خلال خدمة HAL، ما يتيح لك إضافة نقاط/فئات تتبّع خاصة بالجهاز. يتم دمج نقاط التتبُّع مع perfetto وatrace/systrace وتطبيق تتبُّع النظام على الجهاز.

واجهات برمجة التطبيقات لتنفيذ نقاط التتبُّع/الفئات هي:

  • تُنشئ دالة listCategories()‎ (vec<TracingCategory> categories)‎.
  • تُنشئ دالة enableCategories(vec<string> categories) القيمة (Status status).
  • تُنشئ دالة disableAllCategories()‎ (Status status)‎.
لمزيد من المعلومات، يُرجى الرجوع إلى تعريف HAL وطريقة التنفيذ التلقائية في AOSP: