استخدام ftrace

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

للحصول على تفاصيل عن وظائف ftrace المتقدّمة غير المتوفّرة من راجع وثائق ftrace في <kernel tree>/Documentation/trace/ftrace.txt

تسجيل أحداث النواة باستخدام السمة atrace

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

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

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

تفعيل أحداث ftrace

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

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

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

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

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

إذا تم تفعيل أحداث إضافية عن طريق الكتابة إلى عُقد sysfs، سيتم لا تتم إعادة ضبطها بواسطة العنوان. نمط شائع لإظهار جهاز 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 التتبع في شكل نصي. لتصورها باستخدام منجنيق، احصل على منقوشة مستودع من GitHub وتشغيل trace2html:

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

بشكل تلقائي، يؤدي ذلك إلى كتابة trace_file.html بالطريقة نفسها الدليل.

ربط الأحداث

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

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

  1. افتح سجلّ ftrace غير الأولي. تُعد آثار التتبع في الإصدارات الأخيرة من سجل النظام مضغوطة بشكل افتراضي:
    • إذا سجّلت سجلّ النظام باستخدام --no-compress، هذا هو ملف html في القسم الذي يبدأ بـ BEGIN TRACE.
    • إذا لم يكن الأمر كذلك، قم بتشغيل html2trace من منقوشة الشجرة (tracing/bin/html2trace) لفك ضغط التتبع
  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 الديناميكي

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

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

  1. إزالة CONFIG_STRICT_MEMORY_RWX (إذا كانت موجودة). إذا كنت تستخدم الإصدار 3.18 أو الأحدث وأسطوانة 64، لم تكن موجودة.
  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، ومحلِّل الاستباقي المتاح. نحن نشدّد على أنصحك بقراءة مستندات نظام ftrace حول هذه المواضيع قبل استخدام لأنها قوية لكنها معقدة. و irqsoff و الاستباقية في المقام الأول مفيدة للتأكد من أن السائقين قد يتركون مقاطعات أثناء المشاهدة أو يتخذون إجراءات استباقية يتم إيقافها لفترة طويلة جدًا.

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


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

استخدام دالة Lockstat

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

ومع ذلك، يستخدم 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، ما يسمح لك بإضافة بيانات تتبُّع خاصة بالجهاز. النقاط/الفئات. يتم دمج نقاط التتبُّع مع مستوى الأداء والتتبّع أو النظام والنظام على الجهاز. لتتبع البيانات.

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

  • listالفئات()generates (vec<TracingCategory>ماس)؛
  • Enableفئات(vec<string> category) يُنتج (حالة الحالة)
  • DisableAllالفئات() ينشئ (حالة الحالة)
لمزيدٍ من المعلومات، راجع تعريف HAL والتنفيذ التلقائي في بروتوكول AOSP: