ftrace הוא כלי לניפוי באגים שעוזר להבין מה קורה הליבה של Linux. בקטעים הבאים מפורטות פונקציונליות בסיסית של ftrace, ftrace שימוש עם atrace (המתעד אירועי ליבה) ומעקב דינמי.
לפרטים על הפונקציונליות של מעקב מתקדם שלא זמינה מ-
systrace, קראו את מסמכי התיעוד של ftrace,
<kernel
tree>/Documentation/trace/ftrace.txt
תיעוד אירועי ליבה באמצעות atrace
atrace (frameworks/native/cmds/atrace
) משתמש באמצעות ftrace כדי לצלם
אירועי ליבה (kernel). בתורו, systrace.py (או run_systrace.py בגרסאות מאוחרות יותר של
Catapult) משתמשים ב-adb
כדי להריץ ב-ATT במכשיר. atrace, מבצע את הפעולות הבאות:
- הגדרת מעקב במצב משתמש באמצעות הגדרת נכס
(
debug.atrace.tags.enableflags
). - מפעיל את פונקציונליות המעקב הרצויה על ידי כתיבה ftrace xsfs. אבל מכיוון ש-ftrace תומך בתכונות נוספות, אפשר להגדיר כמה צומתי sysfs בעצמכם ואז להשתמש ב-atrace.
למעט מעקב בזמן האתחול, הסתמכו על השימוש ב-atrace כדי להגדיר את לערך המתאים. הנכס הוא קצת מסכה ואין דרך לקבוע את הערכים הנכונים, חוץ מאשר על הכותרת המתאימה (שעשוי להשתנות בין גרסאות Android).
הפעלת אירועי ftrace
צומתי ה-sysfs של ftrace נמצאים ב-/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, הם:
לא יאופסו על ידי atrace. דפוס נפוץ
להעלאת נתוני מכשיר של Qualcomm להפעלה של kgsl
(GPU)
mdss
(להציג צינור עיבוד נתונים) ולאחר מכן להשתמש ברצף או
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
ה-tracking_output יוצר את המעקב בצורת טקסט. כדי להמחיש את הנתונים באמצעות קאטפולט, הנה קטפולט repository מ-GitHub ומריצים את trace2html:
catapult/tracing/bin/trace2html ~/path/to/trace_file
כברירת מחדל, כתוב trace_file.html
באותו אופן
תיאום אירועים
לעיתים קרובות מומלץ להסתכל על התצוגה החזותית של Catapult ועל עקבות יומן בו-זמנית, לדוגמה, חלק מאירועי ftrace (במיוחד לספקים ספציפיים) ) לא). אבל חותמות הזמן של Catapult ביחס לאירוע הראשון במעקב או לחותמת זמן ספציפית שנשלף על ידי מרוץ תהליכים, ואילו חותמות הזמן הגולמיות של ה-ftrace מבוססות על מקור השעון המוחלט בליבה (kernel) של Linux.
כדי למצוא אירוע ftrace מסוים מאירוע Catapult:
- פותחים את היומן הגולמי של ftrace. עקבות בגרסאות עדכניות של systrace
דחוס כברירת מחדל:
- אם תיעדת את המערכת באמצעות
--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 ללא מרוץ), אז הזמנים יהיו יחסיים מהאירוע הראשון ביומן המעקב.- מוסיפים את חותמת הזמן היחסית (באלפיות השנייה) לערך
parent_ts
(בשניות). - מחפשים את חותמת הזמן החדשה.
- מוסיפים את חותמת הזמן היחסית (באלפיות השנייה) לערך
השלבים האלה צריכים למקם אתכם באירוע (או לפחות קרוב מאוד אליו).
שימוש במעקב דינמי
כש-systrace ו-ftrace רגיל לא מספיקים, יש אחד אחרון יש תשובה זמינה: ftrace דינמי. ftrace דינמית כרוכה בשכתוב של קוד הליבה אחרי האתחול, וכתוצאה מכך הוא לא זמין בסביבת הייצור של הליבה מטעמי אבטחה. עם זאת, כל באג קשה בביצועים בסופו של דבר, נגרם נזק מהשורש של הבעיה בין 2015 ל-2016 באמצעות ftrace דינמית. זה במיוחד הוא יעיל לניפוי באגים בקטעי שינה רציפים, כי אפשר לקבל דוח קריסות בליבה (kernel) בכל פעם שנכנסים לפונקציה שמפעילה שינה רציפה. אפשר גם לנפות באגים בקטעים שבהם יש הפרעות והפסקות זמניות בשירות, וכך אתם יכולים הוא שימושי מאוד להוכחת בעיות.
כדי להפעיל ftrace דינמי, עורכים את defconfig של הליבה:
- מסירים את CONFIG_STRICT_MEMORY_RWX (אם קיים). אם משתמשים ב-3.18 או newer ו-arm64, הוא לא שם.
- מוסיפים את הערכים הבאים: CONFIG_DYNAMIC_FTRACE=y, CONFIG_FUNCTION_TRACER=y, CONFIG_IRQSOFF_TRACER=y, CONFIG_FUNCTION_PROFILER=y, ו-CONFIG_PREEMPT_TRACER=y
- בנייה מחדש והפעלה של הליבה (kernel) החדשה.
- מבצעים את הפעולות הבאות כדי לבדוק אם יש כלי מעקב זמינים:
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 profiler, וב-preemptoff profiler. אנחנו מאוד מומלץ לקרוא את המסמכים של ftrace לפי הנושאים האלה לפני שמשתמשים כי הם עוצמתיים אבל מורכבים. irqsoff ו-preemptoff הם בעיקר שימושית כדי לאשר שנהגים משאירים הפרעות או מבצעים מראש הושבת למשך זמן רב מדי.
הכלי לניתוח ביצועים של פונקציות הוא האפשרות הטובה ביותר לבעיות בביצועים, ולרוב כדי למצוא לאן קוראים לפונקציה.
אם הנתונים מהכלי לניתוח ביצועים של פונקציות לא ספציפיים מספיק, אפשר לשלב
ftrace trackingpoints באמצעות פרופיל הפונקציה. ניתן להפעיל אירועי ftrace
בדיוק באותו אופן כרגיל, והם ישולבו עם המעקב שלך.
זה מעולה אם יש מדי פעם שינה ארוכה שלא רצתה
הפונקציה שרוצים לנפות בה באגים: מגדירים את מסנן ftrace לפונקציה הרצויה,
להפעיל נקודות מעקב, לעקוב אחרי המעקב. אפשר לנתח את המעקב שנוצר באמצעות
trace2html
, אפשר למצוא את האירוע הרצוי ולקבל דוחות קריסות בקרבת מקום
בנתוני המעקב הגולמיים.
שימוש ב-lockstat
לפעמים, ftrace אינו מספיק וצריך לבצע ניפוי באגים בכל מה שנראה
להיות תחרות על נעילת ליבה (kernel). יש עוד אפשרות ליבה אחת שכדאי לנסות:
CONFIG_LOCK_STAT
זהו מוצא אחרון מאחר שהוא
קשה מאוד לעבוד במכשירי Android מפני שהיא מגדילה את נפח
ליבה (kernel) מעבר למה שרוב המכשירים יכולים לטפל בו.
עם זאת, Lockstat משתמש בניפוי באגים
נעילת תשתית, והיא שימושית להרבה אפליקציות אחרות. כולם
כשעובדים על העלאת נתונים של מכשירים,
אתם אמורים למצוא דרך להפעיל את האפשרות הזאת
בכל מכשיר כי יגיע זמן שבו
"אם רק יכולתי להפעיל את LOCK_STAT
, יכולתי לאשר או להפריך את ההגדרה הזו
כבעיה בחמש דקות במקום בחמישה ימים".
אם ניתן לאתחל ליבה באמצעות אפשרות ההגדרה, מעקב הנעילה דומה ל- 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
.
שימוש בנקודות מעקב של ספקים
קודם כדאי להשתמש בנקודות מעקב (trackingpoint) ב-upstream, אבל לפעמים תצטרכו להשתמש בנקודות מעקב של הספק:
{ "gfx", "Graphics", ATRACE_TAG_GRAPHICS, { { OPT, "events/mdss/enable" }, { OPT, "events/sde/enable" }, { OPT, "events/mali_systrace/enable" }, } },
ניתן להרחיב את נקודות המעקב באמצעות שירות HAL, וכך להוסיף נתוני מעקב ספציפיים למכשיר נקודות/קטגוריות. נקודות מעקב משולבות עם Perfetto, Atrace/systrace והמערכת במכשיר אפליקציית מעקב.
ממשקי ה-API להטמעה של נקודות מעקב/קטגוריות הם:
- listcategories()generates (vec<TracingCategory> קטגוריות);
- EnableCategory(vec<string> categories) יוצר (סטטוס סטטוס);
- disabledAllCategory() יוצר (סטטוס סטטוס);