מאמר זה מתאר כמה טיפים וטריקים לאיתור באגים בשמע אנדרואיד.
כיור טי
"כיור הטי" הוא תכונת ניפוי באגים של AudioFlinger, זמינה בבנייה מותאמות אישית בלבד, לשמירה על קטע קצר של אודיו עדכני לניתוח מאוחר יותר. זה מאפשר השוואה בין מה שהושמע או הוקלט בפועל לעומת מה שהיה צפוי.
למען הפרטיות כיור הטי מושבת כברירת מחדל, הן בזמן ההידור והן בזמן הריצה. כדי להשתמש בכיור הטי, תצטרך להפעיל אותו על ידי קומפילציה מחדש, וגם על ידי הגדרת מאפיין. הקפד להשבית תכונה זו לאחר שתסיים לנפות באגים; אין להשאיר את כיור הטי מופעל בבניית ייצור.
ההוראות בסעיף זה מיועדות לאנדרואיד 7.x ומעלה. עבור Android 5.x ו-6.x, החלף את /data/misc/audioserver
ב- /data/misc/media
. בנוסף, עליך להשתמש ב-userdebug או ב-eng build. אם אתה משתמש ב-userdebug build, השבת את verity באמצעות:
adb root && adb disable-verity && adb reboot
הגדרה בזמן הידור
-
cd frameworks/av/services/audioflinger
- ערוך
Configuration.h
. - בטל תגובה
#define TEE_SINK
. - בנה מחדש
libaudioflinger.so
. -
adb root
-
adb remount
- דחוף או סנכרן את
libaudioflinger.so
החדש ל-/system/lib
של המכשיר.
הגדרת זמן ריצה
-
adb shell getprop | grep ro.debuggable
אשר שהפלט הוא:[ro.debuggable]: [1]
-
adb shell
-
ls -ld /data/misc/audioserver
ודא שהפלט הוא:
drwx------ media media ... media
אם הספרייה לא קיימת, צור אותה באופן הבא:
mkdir /data/misc/audioserver
chown media:media /data/misc/audioserver
-
echo af.tee=# > /data/local.prop
כאשר הערךaf.tee
הוא מספר המתואר להלן. -
chmod 644 /data/local.prop
-
reboot
ערכים עבור נכס af.tee
הערך של af.tee
הוא מספר בין 0 ל-7, המבטא סכום של מספר ביטים, אחד לכל תכונה. ראה את הקוד ב- AudioFlinger::AudioFlinger()
ב- AudioFlinger.cpp
להסבר על כל סיביות, אך בקצרה:
- 1 = קלט
- 2 = פלט FastMixer
- 4 = AudioRecord ו- AudioTrack לכל רצועה
אין עדיין סיביות למאגר עמוק או למיקסר רגיל, אבל אתה יכול לקבל תוצאות דומות באמצעות "4".
בדוק ורכש נתונים
- הפעל את בדיקת השמע שלך.
-
adb shell dumpsys media.audio_flinger
- חפש שורה בפלט של
dumpsys
כגון זה:
tee copied to /data/misc/audioserver/20131010101147_2.wav
זהו קובץ PCM .wav. - לאחר מכן
adb pull
כל קבצי/data/misc/audioserver/*.wav
המעניינים אותם; שים לב ששמות קבצי dump ספציפיים למסלול אינם מופיעים בפלטdumpsys
, אך עדיין נשמרים ב-/data/misc/audioserver
עם סגירת המסלול. - סקור את קבצי ה-dump לחששות פרטיות לפני שתשתף עם אחרים.
הצעות
נסה את הרעיונות הבאים לקבלת תוצאות שימושיות יותר:
- השבת את צלילי המגע ולחיצות מקש כדי להפחית את ההפרעות בפלט הבדיקה.
- הגדל את כל עוצמת הקול.
- השבת אפליקציות שמשמיעות קול או מקליטות מהמיקרופון, אם הן לא מעניינות את המבחן שלך.
- מטילות ספציפיות למסלול נשמרות רק כאשר המסלול סגור; ייתכן שתצטרך לסגור אפליקציה בכוח כדי לזרוק את הנתונים הספציפיים למסלול שלה
- בצע את ה-
dumpsys
מיד לאחר הבדיקה; יש כמות מוגבלת של שטח הקלטה זמין. - כדי לוודא שלא תאבד את קובצי ה-dump שלך, העלה אותם למארח שלך מעת לעת. רק מספר מוגבל של קבצי dump נשמר; מזבלות ישנות יותר יוסרו לאחר הגבלה זו.
לשחזר
כפי שצוין לעיל, אין להשאיר את תכונת כיור הטי פעילה. שחזר את המבנה והמכשיר שלך באופן הבא:
- החזר את השינויים בקוד המקור ל-
Configuration.h
. - בנה מחדש
libaudioflinger.so
. - דחוף או סנכרן את
libaudioflinger.so
המשוחזר ל-/system/lib
של המכשיר. -
adb shell
-
rm /data/local.prop
-
rm /data/misc/audioserver/*.wav
-
reboot
media.log
פקודות מאקרו של ALOGx
ה-API הסטנדרטי לרישום שפת Java ב-Android SDK הוא android.util.Log .
ה-API של שפת C המקביל ב-Android NDK הוא __android_log_print
המוצהר ב- <android/log.h>
.
בתוך החלק המקורי של מסגרת אנדרואיד, אנו מעדיפים פקודות מאקרו בשם ALOGE
, ALOGW
, ALOGI
, ALOGV
וכו'. הם מוצהרים ב- <utils/Log.h>
, ולמטרות מאמר זה נתייחס אליהם ביחד כ- ALOGx
.
כל ממשקי ה-API הללו קלים לשימוש ומובנים היטב, כך שהם נפוצים בכל פלטפורמת האנדרואיד. בפרט תהליך mediaserver
, הכולל את שרת הסאונד AudioFlinger, עושה שימוש נרחב ALOGx
.
עם זאת, יש כמה מגבלות ל- ALOGx
ולחברים:
- הם רגישים ל"דואר זבל ביומן": מאגר היומן הוא משאב משותף כך שהוא יכול בקלות לעלות על גדותיו עקב רשומות יומן לא קשורות, וכתוצאה מכך החמצת מידע. גרסת
ALOGV
מושבתת בזמן ההידור כברירת מחדל. אבל כמובן שאפילו זה יכול לגרום לספאם ביומן אם זה מופעל. - קריאות מערכת הליבה הבסיסיות עלולות לחסום, ואולי לגרום להיפוך עדיפות וכתוצאה מכך הפרעות ואי דיוקים במדידה. זה מדאיג במיוחד שרשורים קריטיים לזמן כמו
FastMixer
ו-FastCapture
. - אם יומן מסוים מושבת כדי להפחית דואר זבל ביומן, אז כל מידע שהיה נקלט על ידי יומן זה יאבד. לא ניתן להפעיל יומן ספציפי רטרואקטיבית, לאחר שמתברר שהיומן היה מעניין.
NBLOG, media.log ו- MediaLogService
ממשקי ה-API NBLOG
והתהליך media.log
המשויך ושירות MediaLogService
יוצרים יחד מערכת רישום חדשה יותר עבור מדיה, ותוכננו במיוחד כדי לטפל בבעיות שלמעלה. אנו נשתמש באופן רופף במונח "media.log" כדי להתייחס לשלושתם, אך באופן קפדני NBLOG
הוא ה-API לרישום C++, media.log
הוא שם תהליך לינוקס, ו- MediaLogService
הוא שירות קלסר אנדרואיד לבחינת היומנים.
"ציר זמן" media.log
הוא סדרה של רשומות יומן שהסדר היחסי שלהן נשמר. לפי המוסכמה, כל שרשור צריך להשתמש בציר הזמן שלו.
יתרונות
היתרונות של מערכת media.log
הם בכך שהיא:
- אינו שולח דואר זבל ביומן הראשי אלא אם כן ועד שיש צורך בכך.
- ניתן לבחון גם כאשר
mediaserver
קורס או נתקע. - אינו חוסם לפי ציר זמן.
- מציע פחות הפרעה לביצועים. (כמובן ששום צורה של רישום לא פולשנית לחלוטין.)
ארכיטקטורה
הדיאגרמה שלהלן מציגה את הקשר בין תהליך mediaserver
לבין תהליך init
, לפני הצגת media.log
:
נקודות בולטות:
-
init
forks ו-execsmediaserver
. -
init
מזהה את המוות שלmediaserver
, ומתפצלת מחדש לפי הצורך. - רישום
ALOGx
אינו מוצג.
התרשים שלהלן מציג את הקשר החדש של הרכיבים, לאחר הוספת media.log
לארכיטקטורה:
שינויים חשובים:
- לקוחות משתמשים
NBLOG
API כדי לבנות ערכי יומן ולצרף אותם למאגר עגול בזיכרון משותף. -
MediaLogService
יכול לזרוק את התוכן של המאגר העגול בכל עת. - המאגר העגול מתוכנן כך שכל פגיעה בזיכרון המשותף לא תקרוס
MediaLogService
, והוא עדיין יוכל לזרוק כמה שיותר מהמאגר שאינו מושפע מהשחיתות. - המאגר העגול אינו חוסם וללא נעילה הן לכתיבת ערכים חדשים והן לקריאת ערכים קיימים.
- לא נדרשות קריאות למערכת הקרנל כדי לכתוב או לקרוא מהמאגר העגול (מלבד חותמות זמן אופציונליות).
איפה להשתמש
נכון לאנדרואיד 4.4, יש רק כמה נקודות יומן ב-AudioFlinger שמשתמשות במערכת media.log
. למרות שממשקי ה-API החדשים אינם קלים לשימוש כמו ALOGx
, הם גם לא קשים במיוחד. אנו ממליצים לך ללמוד את מערכת הרישום החדשה לאותם מקרים שבהם היא חיונית. בפרט, זה מומלץ עבור שרשורים של AudioFlinger שחייבים לרוץ בתדירות גבוהה, מעת לעת וללא חסימה כגון שרשורי FastMixer
ו- FastCapture
.
איך להישתמש
הוסף יומנים
ראשית, עליך להוסיף יומנים לקוד שלך.
בשרשורי FastMixer
ו- FastCapture
, השתמש בקוד כגון זה:
logWriter->log("string"); logWriter->logf("format", parameters); logWriter->logTimestamp();
מכיוון שציר הזמן הזה NBLog
משמש רק את השרשורים של FastMixer
ו- FastCapture
, אין צורך בהדרה הדדית.
בשרשורים אחרים של AudioFlinger, השתמש mNBLogWriter
:
mNBLogWriter->log("string"); mNBLogWriter->logf("format", parameters); mNBLogWriter->logTimestamp();
עבור שרשורים שאינם FastMixer
ו- FastCapture
, ניתן להשתמש בציר הזמן NBLog
של השרשור הן על ידי השרשור עצמו והן על ידי פעולות מקשר. NBLog::Writer
אינו מספק כל אי הכללה הדדית מרומזת לכל ציר זמן, אז ודא שכל היומנים מתרחשים בהקשר שבו ה-mutex mLock
של השרשור מוחזק.
לאחר שהוספת את היומנים, בנה מחדש את AudioFlinger.
זהירות: נדרש ציר זמן נפרד NBLog::Writer
לכל שרשור, כדי להבטיח את בטיחות השרשור, מכיוון שצירי זמן משמיטים את המוטקסים לפי התכנון. אם אתה רוצה שיותר משרשור אחד ישתמש באותו ציר זמן, אתה יכול להגן עם mutex קיים (כמתואר לעיל עבור mLock
). או שאתה יכול להשתמש במעטפת NBLog::LockedWriter
במקום NBLog::Writer
. עם זאת, זה שולל את היתרון העיקרי של API זה: ההתנהגות הבלתי חוסמת שלו.
ה-API המלא NBLog
נמצא ב- frameworks/av/include/media/nbaio/NBLog.h
.
הפעל את media.log
media.log
מושבת כברירת מחדל. הוא פעיל רק כאשר הנכס ro.test_harness
הוא 1
. אתה יכול להפעיל את זה על ידי:
adb root
adb shell
echo ro.test_harness=1 > /data/local.prop
chmod 644 /data/local.prop
reboot
החיבור אבד במהלך אתחול מחדש, אז:
adb shellהפקודה
ps media
תציג כעת שני תהליכים:- media.log
- שרת מדיה
שימו לב למזהה התהליך של mediaserver
למועד מאוחר יותר.
הצג את קווי הזמן
אתה יכול לבקש באופן ידני dump יומן בכל עת. פקודה זו מציגה יומנים מכל קוי הזמן הפעילים והאחרונים, ולאחר מכן מנקה אותם:
dumpsys media.log
שים לב שלפי עיצוב קווי זמן הם עצמאיים, ואין אפשרות למזג קווי זמן.
שחזור יומנים לאחר מוות של שרת המדיה
כעת נסה להרוג את תהליך mediaserver
: kill -9 #
, כאשר # הוא מזהה התהליך שציינת קודם לכן. אתה אמור לראות dump מ- media.log
ב- logcat
הראשי, המציגה את כל היומנים שהובילו לקריסה.
dumpsys media.log