تُعد 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 فقط:
- اضبط حجم المخزن المؤقت على قيمة كبيرة بما يكفي للتتبُّع:
echo 96000 > /sys/kernel/tracing/buffer_size_kb
- تفعيل التتبع:
echo 1 > /sys/kernel/tracing/tracing_on
- قم بإجراء الاختبار، ثم قم بإيقاف التتبع:
echo 0 > /sys/kernel/tracing/tracing_on
- حذف بيانات التتبّع:
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:
- افتح سجلّ ftrace غير الأولي. تُعد آثار التتبع في الإصدارات الأخيرة من سجل النظام
مضغوطة بشكل افتراضي:
- إذا سجّلت سجلّ النظام باستخدام
--no-compress
، هذا هو ملف html في القسم الذي يبدأ بـ BEGIN TRACE. - إذا لم يكن الأمر كذلك، قم بتشغيل html2trace من
منقوشة
الشجرة (
tracing/bin/html2trace
) لفك ضغط التتبع
- إذا سجّلت سجلّ النظام باستخدام
- العثور على الطابع الزمني النسبي في تصور Catapult.
- ابحث عن خط في بداية التتبّع يحتوي على
tracing_mark_sync
من المفترض أن يظهر على النحو التالي:<5134>-5134 (-----) [003] ...1 68.104349: tracing_mark_write: trace_event_clock_sync: parent_ts=68.104286
إذا كان هذا الخط غير موجود (أو إذا استخدمت ftrace بدون atrace)، فعندئذ ستكون التوقيتات نسبية من الحدث الأول في سجل ftrace.- أضف الطابع الزمني النسبي (بالمللي ثانية) إلى القيمة في
parent_ts
(بالثواني). - ابحث عن الطابع الزمني الجديد.
- أضف الطابع الزمني النسبي (بالمللي ثانية) إلى القيمة في
من المفترض أن تضعك هذه الخطوات في الحدث (أو على الأقل في وقت قريب جدًا منه).
استخدام نظام ftrace الديناميكي
عندما لا يكون تتبع النظام وبروتوكول ftrace كافيين، هناك خطوة أخيرة تتوفّر إمكانية استرداد الحساب: Dynamic ftrace. تتضمن عملية ftrace الديناميكية إعادة الكتابة تعليمات برمجية kernel بعد التشغيل، ونتيجةً لذلك لا تتوفر في مرحلة الإنتاج لأسباب تتعلق بالأمان. ومع ذلك، فإن كل خطأ صعب في الأداء في كان عاما 2015 و2016 هما السبب الأساسي في استخدام نظام ftrace الديناميكي. من المهم فعّالة في تصحيح أخطاء فترات النوم غير المنقطعة لأنه يمكنك تتبُّع تسلسل استدعاء الدوال البرمجية في النواة في كل مرة تصل فيها إلى الوظيفة تؤدي إلى نوم لا تقاطعه. ويمكنك أيضًا تصحيح أخطاء الأقسام التي تم إيقاف مقاطعاتها وإجراءات استباقية، ما يؤدي إلى مفيدة جدًا لإثبات المشكلات.
لتفعيل التتبع الديناميكي، عدِّل إعدادات defconfig الخاصة بالنواة:
- إزالة CONFIG_STRICT_MEMORY_RWX (إذا كانت موجودة). إذا كنت تستخدم الإصدار 3.18 أو الأحدث وأسطوانة 64، لم تكن موجودة.
- أضف ما يلي: CONFIG_DYNAMIC_FTRACE=y, CONFIG_FUNCTION_TRACER=y, CONFIG_IRQSOFF_TRACER=y وCONFIG_FUNCTION_PROFILER=y وCONFIG_PREEMPT_TRACER=y
- أعِد إنشاء النواة الجديدة وشغِّلها.
- يمكنك تشغيل ما يلي للبحث عن برامج التتبُّع المتاحة:
cat /sys/kernel/tracing/available_tracers
- تأكَّد من أنّ الأمر يعرض
function
وirqsoff
preemptoff
، وpreemptirqsoff
. - شغِّل ما يلي لضمان عمل نظام ftrace الديناميكي:
cat /sys/kernel/tracing/available_filter_functions | grep <a function you care about>
بعد الانتهاء من هذه الخطوات، يكون لديك ftrace الديناميكي ومحلل الدوال ومحلِّل irqsoff، ومحلِّل الاستباقي المتاح. نحن نشدّد على أنصحك بقراءة مستندات نظام ftrace حول هذه المواضيع قبل استخدام لأنها قوية لكنها معقدة. و irqsoff و الاستباقية في المقام الأول مفيدة للتأكد من أن السائقين قد يتركون مقاطعات أثناء المشاهدة أو يتخذون إجراءات استباقية يتم إيقافها لفترة طويلة جدًا.
يعد محلّل الدوال الخيار الأفضل لمشاكل الأداء وغالبًا ما تُستخدم لمعرفة مكان استدعاء الدالة.
عرض المشكلة: صورة نطاق عالي الديناميكية + عدسة دوّارة
في هذه المشكلة، استخدام هاتف Pixel XL لالتقاط صورة بتقنية HDR+ ثم على الفور أدى تدوير عدسة الكاميرا إلى حدوث عطل في كل مرة. استخدمنا محلل الدالة وتصحيح المشكلة في أقل من ساعة. لمتابعة المثال، نزِّل الملف المضغوط للتتبُّعات (والذي يكون أيضًا يتضمن التتبعات الأخرى المُشار إليها في هذا القسم)، وفك ضغط الملف، ثم افتح trace_30898724.html في متصفحك.
يعرض التتبُّع العديد من سلاسل المحادثات المحظورة في عملية خادم الكاميرا.
نوم لا يمكن انقطاعه على ion_client_destroy
هذا سعر باهظ
ولكن ينبغي استدعاؤها بشكل نادر جدًا لأن عملاء الأيونات لا بد من استدعائها
العديد من التخصيصات. في البداية، وقع اللوم على الكود السداسي في
هاليد، التي كانت بالفعل من الجناة (أنشأت عميلًا جديدًا لكل
أيون وأتلاف هذا العميل عند تحرير الحصة المخصصة، مما
كانت مكلفة للغاية). الانتقال إلى عميل أيون واحد لجميع عناصر السداسي
المخصصات تحسنت الوضع، ولكن لم يتم إصلاح العطل.
في هذه المرحلة نحتاج إلى معرفة من يتصل بـ ion_client_destroy
،
لذا فقد حان الوقت لاستخدام محلّل الدالة:
- نظرًا لإعادة تسمية الدوال أحيانًا بواسطة برنامج التحويل البرمجي، تأكد
يتوفر
ion_client_destroy
باستخدام:cat /sys/kernel/tracing/available_filter_functions | grep ion_client_destroy
- بعد التأكّد من توفّر التطبيق، استخدِمه كفلتر تتبُّع تتبُّع الملفات (ftrace):
echo ion_client_destroy > /sys/kernel/tracing/set_ftrace_filter
- تفعيل محلّل الدالة:
echo function > /sys/kernel/tracing/current_tracer
- يمكنك تفعيل عمليات تتبُّع تسلسل استدعاء الدوال البرمجية عند استدعاء دالة فلتر:
echo func_stack_trace > /sys/kernel/tracing/trace_options
- زيادة حجم المخزن المؤقت:
echo 64000 > /sys/kernel/tracing/buffer_size_kb
- يمكنك تفعيل ميزة التتبُّع:
echo 1 > /sys/kernel/tracing/trace_on
- أجرِ الاختبار واحصل على تأثير:
cat /sys/kernel/tracing/trace > /data/local/tmp/trace
- يمكنك عرض عملية تتبُّع تسلسل استدعاء الدوال البرمجية للاطّلاع على الكثير والكثير من عمليات تتبُّع تسلسل استدعاء الدوال البرمجية:
cameraserver-643 [003] ...1 94.192991: ion_client_destroy <-ion_release cameraserver-643 [003] ...1 94.192997: <stack trace> => ftrace_ops_no_ops => ftrace_graph_call => ion_client_destroy => ion_release => __fput => ____fput => task_work_run => do_notify_resume => work_pending
فبناءً على فحص سائق الأيون، يمكننا ملاحظة أن
يتم إرسال رسالة غير مرغوب فيها إلى "ion_client_destroy
" من خلال إغلاق دالة في مساحة المستخدم.
fd إلى /dev/ion
، وليس برنامج تشغيل نواة عشوائي. من خلال البحث في
قاعدة رموز Android لـ \"/dev/ion\"
، نبحث عن العديد من برامج تشغيل الموردين
تفعل نفس الشيء مثل برنامج التشغيل السداسي العشري والفتح/الخاتمة
/dev/ion
(إنشاء عميل أيون جديد وإتلافه) في كل مرة
إلى تخصيص أيون جديد. إن تغيير تلك إلى
استخدام
برنامج أيون واحد طوال مدة العملية لإصلاح الخطأ.
إذا لم تكن البيانات من محدِّد الدوال محددة بما يكفي، فيمكنك دمج
نقاط تتبع ftrace باستخدام محلل الدالة. يمكن تفعيل أحداث ftrace في
بالطريقة نفسها تمامًا كالعادة، سيتم تشذيبها مع آثار الأثر.
هذا أمر رائع إذا كان هناك نوم طويل عرضي غير متقطع في غرفة نوم
التي تريد تصحيحها: اضبط فلتر ftrace على الدالة التي تريدها،
تمكين نقاط التتبع، وإجراء تعقب. يمكنك تحليل التتبع الناتج باستخدام
trace2html
، ابحث عن الحدث الذي تريده، ثم احصل على عمليات تتبُّع تسلسل استدعاء الدوال البرمجية القريبة
في التتبع الأولي.
استخدام دالة Lockstat
في بعض الأحيان، لا تكون ميزة ftrace كافية وتحتاج حقًا إلى تصحيح أخطاء ما يظهر.
الصراع على قفل النواة. هناك خيار آخر من خيارات النواة التي تستحق التجربة:
CONFIG_LOCK_STAT
هذا هو الملاذ الأخير لأنه
العمل على أجهزة Android لأنه يعمل على تضخيم حجم
kernel بخلاف ما يمكن لمعظم الأجهزة التعامل معه.
ومع ذلك، يستخدم lockstat تصحيح الأخطاء
قفل البنية الأساسية، وهو أمر مفيد للعديد من التطبيقات الأخرى. كل الأقسام
العمل على إظهار الجهاز يجب أن يكتشف طريقة ما لجعل هذا الخيار يعمل
كل جهاز لأنه سيكون هناك وقت تعتقد
"إذا كان بإمكاني فقط تفعيل LOCK_STAT
، يمكنني تأكيد ذلك أو دحضه.
ظهور المشكلة في خمس دقائق بدلاً من خمسة أيام".
عرض المشكلة: توقف في SCHED_FIFO عند تشغيل النوى بأقصى سرعة مع الأجهزة غير SCHED_FIFO
في هذه المشكلة، توقفت سلسلة تعليمات SCHED_FIFO عند بلوغ الحد الأقصى لعدد النوى. من خلال سلسلة تعليمات غير SCHED_FIFO كانت لدينا آثار تُظهر قفلاً كبيرًا التنافس على fd في تطبيقات الواقع الافتراضي، ولكننا لم نتمكن من التعرف على الجدول الزمني المستخدم بسهولة. لمتابعة المثال، نزِّل الملف المضغوط ملف آثار الأنشطة (يشمل أيضًا آثار الأنشطة الأخرى المُشار إليها في هذا )، فقم بفك ضغط الملف، ثم افتح ملف trace_30905547.html في المتصفح.
افترضنا أن الأصل بحد ذاته كان مصدرًا للنزاع حول القفل، عندما سوف تبدأ سلسلة المحادثات ذات الأولوية المنخفضة في الكتابة على الممر ftrace ثم من قبل أن يتم فتح القفل. هذا سيناريو من أسوأ الحالات بسبب مزيج من سلاسل المحادثات ذات الأولوية المنخفضة للغاية التي كانت تتم كتابتها بالإضافة إلى بعض السلاسل ذات الأولوية الأعلى التي تدور على وحدات المعالجة المركزية محاكاة جهاز محمّل بالكامل.
بما أنّنا لم نتمكّن من استخدام بروتوكول ftrace لتصحيح الأخطاء، نجحنا في العمل على LOCK_STAT
.
وبعد ذلك أوقِف جميع أنشطة التتبُّع الأخرى من التطبيق. أظهرت النتائج القفل
كان هذا النزاع في الواقع بسبب عدم ظهور أي من هذه الخلافات في
تتبع القفل عندما لم يكن ftrace قيد التشغيل.
إذا كان بإمكانك تشغيل نواة باستخدام خيار التهيئة، فإن تتبع القفل يشبه :ftrace
- تفعيل التتبع:
echo 1 > /proc/sys/kernel/lock_stat
- أجرِ الاختبار.
- إيقاف التتبُّع:
echo 0 > /proc/sys/kernel/lock_stat
- تتبُّع البيانات:
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الفئات() ينشئ (حالة الحالة)