خواندن گزارش‌های اشکال

وجود اشکالات در هر نوع توسعه‌ای یک واقعیت است—و گزارش‌های اشکال برای شناسایی و حل مشکلات حیاتی هستند. همه نسخه‌های Android از ثبت گزارش اشکال با Android Debug Bridge (adb) پشتیبانی می‌کنند؛ Android نسخه ۴.۲ و بالاتر از گزینه توسعه‌دهنده برای دریافت گزارش اشکال و هم‌رسانی ازطریق ایمیل، Drive، و غیره پشتیبانی می‌کند.

گزارش‌های اشکال Android حاوی dumpsys، dumpstate، و logcat داده در قالب نوشتاری (‎.txt) است که به شما امکان می‌دهد به‌راحتی محتوای خاصی را جستجو کنید. بخش‌های زیر جزئیات عناصر گزارش اشکال را شرح می‌دهند، مشکلات رایج را توصیف می‌کنند، و نکته‌های مفید و grep فرمان برای یافتن گزارش‌های مربوط به آن اشکالات ارائه می‌دهند. اکثر بخش‌ها همچنین شامل مثال‌هایی برای فرمان و برونداد grep و/یا برونداد dumpsys هستند.

Logcat

گزارش logcat تخلیه مبتنی بر رشته از همه اطلاعات logcat است. بخش سیستم برای چارچوب رزرو شده است و سابقه طولانی‌تری نسبت‌به اصلی دارد که شامل همه موارد دیگر است. هر خط معمولاً با timestamp UID PID TID log-level شروع می‌شود، هرچند ممکن است UID در نسخه‌های قدیمی‌تر Android فهرست نشده باشد.

مشاهده گزارش رویداد

این گزارش حاوی نمایش‌های رشته‌ای از پیام‌های گزارش با قالب باینری است. این گزارش نسبت‌به گزارش logcat نویز کمتری دارد اما خواندن آن کمی دشوارتر است. هنگام مشاهده گزارش‌های رویداد، می‌توانید این بخش را برای شناسه پردازش (PID) خاصی جستجو کنید تا ببینید پردازش چه کاری انجام داده است. قالب پایه این است: timestamp PID TID log-level log-tag tag-values.

سطوح گزارش شامل موارد زیر است:

  • V: مفصل
  • D: اشکال‌زدایی
  • I: information
  • W: هشدار
  • E: خطا

 

برای دیگر برچسب‌های مفید گزارش وقایع، به /services/core/java/com/android/server/EventLogTags.logtags مراجعه کنید.

خطاهای ANR و بن‌بست‌ها

گزارش‌های اشکال می‌تواند به شما کمک کند علت خطاهای Application Not Responding (ANR) و رویدادهای بن‌بست را شناسایی کنید.

شناسایی برنامه‌هایی که پاسخ نمی‌دهند

وقتی برنامه‌ای در مدت زمان مشخصی پاسخ نمی‌دهد، معمولاً به‌دلیل مسدود شدن یا مشغول بودن رشته اصلی، سیستم فرایند را متوقف می‌کند و پشته را در /data/anr تخلیه می‌کند. برای پیدا کردن عامل ANR، در گزارش رویداد باینری، am_anr را grep کنید.

همچنین می‌توانید ANR in را در گزارش logcat جستجو کنید، این گزارش اطلاعات بیشتری درباره آنچه در زمان ANR از CPU استفاده می‌کرده است ارائه می‌دهد.

یافتن ردیابی‌های پشته‌ای

اغلب می‌توانید ردیابی پشته‌ای را که با ANR مطابقت دارد پیدا کنید. مطمئن شوید مُهر زمان و PID در ردیابی‌های ماشین مجازی با ANR که درحال بررسی آن هستید مطابقت داشته باشد، سپس رشته اصلی فرایند را بررسی کنید. به‌خاطر داشته باشید:

  • رشته اصلی فقط به شما می‌گوید که رشته در زمان ANR چه کاری انجام می‌داده است، که ممکن است با علت واقعی ANR مطابقت داشته باشد یا نداشته باشد. (پشته در گزارش اشکال ممکن است بی‌گناه باشد؛ ممکن است چیز دیگری برای مدت طولانی گیر کرده باشد—اما نه آنقدر طولانی که ANR ایجاد کند—قبل‌از اینکه از گیر خارج شود.)
  • ممکن است بیش‌از یک مجموعه ردیابی پشته (VM TRACES JUST NOW و VM TRACES AT LAST ANR) وجود داشته باشد. مطمئن شوید که بخش درست را مشاهده می‌کنید.

یافتن بن‌بست‌ها

بن‌بست‌ها اغلب ابتدا به‌صورت ANR ظاهر می‌شوند زیرا رشته‌ها گیر می‌کنند. اگر بن‌بست به سرور سیستم برسد، نگهبان درنهایت آن را متوقف می‌کند و منجر به ورودی مشابهی در گزارش می‌شود: WATCHDOG KILLING SYSTEM PROCESS. از دیدگاه کاربر، دستگاه بازراه‌اندازی می‌شود، اگرچه ازنظر فنی این یک بازراه‌اندازی زمان اجرا است نه یک بازراه‌اندازی واقعی.

  • در بازراه‌اندازی زمان اجرا، سرور سیستم ازکار می‌افتد و بازراه‌اندازی می‌شود؛ کاربر می‌بیند که دستگاه به پویانمایی راه‌اندازی برمی‌گردد.
  • در بازراه‌اندازی، هسته ازکارافتاده است؛ کاربر می‌بیند که دستگاه به نشان‌واره راه‌اندازی Google برمی‌گردد.

برای پیدا کردن بن‌بست‌ها، بخش‌های ردگیری VM را برای الگوی رشته A که منتظر چیزی است که توسط رشته B نگه داشته شده است، بررسی کنید. رشته B نیز به نوبه خود منتظر چیزی است که توسط رشته A نگه داشته شده است.

فعالیت‌ها

فعالیت جزء برنامه‌ای است که صفحه‌ای را فراهم می‌کند تا کاربران با آن تعامل کنند و کارهایی مثل شماره‌گیری، عکس گرفتن، ارسال ایمیل، و غیره را انجام دهند. از دیدگاه گزارش اشکال، فعالیت یک کار واحد و متمرکز است که کاربر می‌تواند انجام دهد، که این امر یافتن فعالیتی را که درطول خرابی در کانون توجه بوده است بسیار مهم می‌کند. فعالیت‌ها (ازطریق ActivityManager) پردازش‌ها را اجرا می‌کنند، بنابراین یافتن همه توقف‌ها و شروع‌های پردازش برای یک فعالیت معین می‌تواند به عیب‌یابی نیز کمک کند.

مشاهده فعالیت‌های متمرکز

برای مشاهده سابقه فعالیت‌های کانونی، am_focused_activity را جستجو کنید.

فرایند مشاهده شروع می‌شود

برای مشاهده سابقه شروع فرایند، Start proc را جستجو کنید.

تعیین اینکه آیا دستگاه درحال کوبیدن است یا نه

برای تعیین اینکه دستگاه درحال تراشیدن است یا نه، افزایش غیرعادی فعالیت در اطراف am_proc_died و am_proc_start را در مدت زمان کوتاهی بررسی کنید.

حافظه

ازآنجایی‌که دستگاه‌های Android اغلب حافظه فیزیکی محدودی دارند، مدیریت حافظه دسترسی تصادفی (RAM) بسیار مهم است. گزارش‌های اشکال حاوی چندین نشانگر کمبود حافظه و همچنین dumpstate است که عکس آنی حافظه را ارائه می‌دهد.

شناسایی حافظه کم

حافظه کم می‌تواند باعث شود سیستم با کشتن برخی‌از فرایندها برای آزاد کردن حافظه و ادامه دادن به شروع فرایندهای دیگر، دچار تلاطم شود. برای مشاهده شواهد تأییدکننده حافظه کم، تراکم‌های am_proc_died و am_proc_start ورودی را در گزارش رویداد باینری بررسی کنید.

کمبود حافظه همچنین می‌تواند تعویض وظایف را کند کند و تلاش‌های بازگشت را ناکام بگذارد (زیرا وظیفه‌ای که کاربر سعی می‌کرد به آن برگردد بسته شده است). اگر راه‌انداز متوقف شده باشد، وقتی کاربر دکمه صفحه اصلی را لمس می‌کند، راه‌انداز مجدداً راه‌اندازی می‌شود و گزارش‌ها نشان می‌دهند که راه‌انداز محتوایش را دوباره بار می‌کند.

مشاهده شاخص‌های تاریخی

ورودی am_low_memory در گزارش رویداد دودویی نشان می‌دهد که آخرین فرایند ذخیره‌شده در حافظه پنهان ازبین رفته است. پس‌از این، سیستم شروع به بستن خدمات می‌کند.

مشاهده نشانگرهای کوبیدن

نشانگرهای دیگر سیستم thrashing (صفحه‌بندی، بازپس‌گیری مستقیم، و غیره) شامل kswapd، kworker، و mmcqd است که چرخه‌ها را مصرف می‌کنند. (به‌خاطر داشته باشید گزارش اشکالی که جمع‌آوری می‌شود می‌تواند بر نشانگرهای کوبیدن تأثیر بگذارد.)

گزارش‌های ANR می‌توانند نمای لحظه‌ای حافظه مشابهی ارائه دهند.

دریافت عکس آنی خاطره

نمای فوری حافظه یک dumpstate است که فرایندهای درحال اجرای Java و محلی را فهرست می‌کند (برای جزئیات، به مشاهده تخصیص‌های کلی حافظه مراجعه کنید). به‌خاطر داشته باشید که نمای کلی فقط وضعیت را در یک لحظه خاص نشان می‌دهد؛ ممکن است سیستم قبل‌از نمای کلی در وضعیت بهتری (یا بدتری) بوده باشد.

همه‌فرستی‌ها

برنامه‌ها برای ارسال رویدادها در برنامه فعلی یا به برنامه دیگر، همه‌فرستی تولید می‌کنند. گیرنده‌های همه‌فرستی در پیام‌های خاصی (ازطریق فیلترها) مشترک می‌شوند و به آن‌ها امکان می‌دهند هم به همه‌فرستی گوش دهند و هم به آن پاسخ دهند. گزارش‌های اشکالات حاوی اطلاعاتی درباره همه‌فرستی‌های ارسال‌شده و همه‌فرستی‌های ارسال‌نشده، و همچنین dumpsys همه گیرنده‌هایی است که به یک همه‌فرستی خاص گوش می‌دهند.

مشاهده همه‌فرستی‌های قدیمی

همه‌فرستی‌های تاریخی همه‌فرستی‌هایی هستند که قبلاً ارسال شده‌اند و به‌ترتیب زمانی معکوس فهرست شده‌اند.

بخش خلاصه نمای کلی از ۳۰۰ پخش زنده پیش‌زمینه‌ای آخر و ۳۰۰ پخش زنده پس‌زمینه‌ای آخر است.

بخش جزئیات حاوی اطلاعات کامل برای ۵۰ همه‌فرستی پیش‌زمینه آخر و ۵۰ همه‌فرستی پس‌زمینه آخر، و همچنین گیرنده‌های هر همه‌فرستی است. گیرنده‌هایی که دارای:

  • ورودی BroadcastFilter در زمان اجرا ثبت می‌شود و فقط به فرایندهایی که درحال‌حاضر درحال اجرا هستند ارسال می‌شود.
  • ورودی ResolveInfo ازطریق ورودی‌های مانیفست ثبت می‌شود. اگر پردازش ResolveInfo ازقبل درحال اجرا نباشد، ActivityManager پردازش آن را شروع می‌کند.

مشاهده همه‌فرستی‌های فعال

همه‌فرستی‌های فعال آن‌هایی هستند که هنوز ارسال نشده‌اند. تعداد زیاد در صف به این معنی است که سیستم نمی‌تواند همه‌فرستی‌ها را به اندازه کافی سریع ارسال کند تا همگام بماند.

مشاهده شنوندگان همه‌فرستی

برای مشاهده فهرست گیرنده‌هایی که به همه‌فرستی گوش می‌دهند، «جدول حل‌کننده گیرنده» را در dumpsys activity broadcasts بررسی کنید. مثال زیر همه گیرنده‌هایی را که به USER_PRESENT گوش می‌دهند نمایش می‌دهد.

درگیری بر سر پایشگر

ثبت رقابت مانیتور گاهی اوقات می‌تواند نشان‌دهنده رقابت واقعی مانیتور باشد، اما اغلب نشان می‌دهد که سیستم آن‌قدر بارگذاری شده است که همه چیز کند شده است. ممکن است رویدادهای نظارت طولانی را که توسط ART در گزارش سیستم یا رویداد ثبت شده‌اند ببینید.

در گزارش سیستم:

10-01 18:12:44.343 29761 29914 W art     : Long monitor contention event with owner method=void android.database.sqlite.SQLiteClosable.acquireReference() from SQLiteClosable.java:52 waiters=0 for 3.914s

در گزارش رویداد:

10-01 18:12:44.364 29761 29914 I dvm_lock_sample: [com.google.android.youtube,0,pool-3-thread-9,3914,ScheduledTaskMaster.java,138,SQLiteClosable.java,52,100]

ترجمه پس‌زمینه‌ای

ترجمه می‌تواند گران باشد و دستگاه را تحت فشار قرار دهد.

وقتی به‌روزرسانی‌های «فروشگاه Google Play» درحال بارگیری است، ممکن است در پس‌زمینه گردآوری انجام شود. در این حالت، پیام‌های برنامه «فروشگاه Google Play» (finsky) و installd قبل‌از پیام‌های dex2oat ظاهر می‌شوند.

همچنین ممکن است هنگام بار کردن برنامه فایل dex که هنوز ترجمه نشده است، ترجمه در پس‌زمینه انجام شود. در این مورد، گزارش finsky یا installd را نخواهید دید.

روایت

ایجاد روایت یک مشکل (چگونگی شروع آن، چه اتفاقی افتاد، سیستم چگونه واکنش نشان داد) نیازمند یک خط زمان محکم از رویدادها است. می‌توانید از اطلاعات موجود در گزارش اشکال برای همگام‌سازی خطوط زمان در چندین گزارش و تعیین مُهر زمان دقیق گزارش اشکال استفاده کنید.

همگام‌سازی خطوط زمان

گزارش اشکال چندین خط زمان موازی را منعکس می‌کند: گزارش سیستم، گزارش رویداد، گزارش هسته، و چندین خط زمان تخصصی برای همه‌فرستی‌ها، آمار باتری، و غیره. متأسفانه، خطوط زمان اغلب بااستفاده از مبناهای زمانی مختلف گزارش می‌شوند.

مُهرهای زمان سیستم و گزارش رویداد در همان منطقه زمانی کاربر است (همان‌طور که بیشتر مُهرهای زمان دیگر هستند). برای مثال، وقتی کاربر روی دکمه صفحه اصلی ضربه می‌زند، گزارش گزارش سیستم این موارد را گزارش می‌کند:

10-03 17:19:52.939  1963  2071 I ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 cmp=com.google.android.googlequicksearchbox/com.google.android.launcher.GEL (has extras)} from uid 1000 on display 0

برای همان کنش، گزارش رویداد این موارد را گزارش می‌کند:

10-03 17:19:54.279  1963  2071 I am_focused_activity: [0,com.google.android.googlequicksearchbox/com.google.android.launcher.GEL]

گزارش‌های هسته (dmesg) از پایه زمانی متفاوتی استفاده می‌کنند و موارد گزارش را با ثانیه‌های سپری‌شده از زمان تکمیل بارگذار بوت برچسب‌گذاری می‌کنند. برای ثبت این بازه زمانی در بازه‌های زمانی دیگر، پیام‌های تعلیق خروج و تعلیق ورود را جستجو کنید:

<6>[201640.779997] PM: suspend exit 2015-10-03 19:11:06.646094058 UTC
…
<6>[201644.854315] PM: suspend entry 2015-10-03 19:11:10.720416452 UTC

ازآنجایی‌که گزارش‌های هسته ممکن است زمان را در حالت تعلیق شامل نشود، باید گزارش را به‌صورت تکه‌تکه بین پیام‌های ورود و خروج از حالت تعلیق ثبت کنید. به‌علاوه، گزارش‌های هسته از منطقه زمانی UTC استفاده می‌کنند و باید با منطقه زمانی کاربر مطابقت داده شوند.

شناسایی زمان گزارش اشکال

برای تعیین زمان تهیه گزارش اشکال، ابتدا گزارش سیستم (Logcat) را برای dumpstate: begin بررسی کنید:

10-03 17:19:54.322 19398 19398 I dumpstate: begin

سپس، مُهر زمان گزارش هسته (dmesg) را برای پیام Starting service 'bugreport' بررسی کنید:

<5>[207064.285315] init: Starting service 'bugreport'...

با درنظر گرفتن هشدارهای ذکرشده در همگام‌سازی خطوط زمان، برای مرتبط کردن این دو رویداد، از آخر به اول کار کنید. اگرچه پس‌از شروع گزارش اشکال اتفاقات زیادی می‌افتد، اما بیشتر فعالیت‌ها مفید نیستند زیرا عمل گرفتن گزارش اشکال سیستم را به‌طور قابل‌توجهی بار می‌کند.

قدرت

گزارش رویداد حاوی وضعیت روشن/خاموش بودن صفحه‌نمایش است، که در آن ۰ یعنی صفحه‌نمایش خاموش است، ۱ یعنی صفحه‌نمایش روشن است، و ۲ یعنی محافظ صفحه‌کلید انجام شده است.

گزارش‌های اشکال همچنین حاوی آمار مربوط به قفل‌های بیداری است، سازوکاری که توسعه‌دهندگان برنامه از آن برای نشان دادن نیاز برنامه خود به روشن ماندن دستگاه استفاده می‌کنند. (برای جزئیات مربوط به قفل‌های بیداری، به PowerManager.WakeLock و روشن نگه داشتن واحد پردازش مرکزی مراجعه کنید.)

آمار مدت زمان تجمیعی قفل بیداری فقط زمانی را که قفل بیداری واقعاً مسئول بیدار نگه داشتن دستگاه است ردیابی می‌کند و شامل زمان روشن بودن صفحه‌نمایش نمی‌شود. علاوه‌براین، اگر چندین قفل بیداری به‌طور هم‌زمان نگهداری شوند، زمان مدت قفل بیداری بین آن قفل‌های بیداری توزیع می‌شود.

برای راهنمایی بیشتر درباره تجسم وضعیت مصرف برق، از Battery Historian استفاده کنید، ابزار متن‌باز Google برای تجزیه‌وتحلیل مصرف‌کنندگان باتری بااستفاده از فایل‌های گزارش اشکال Android.

بسته‌ها

بخش DUMP OF SERVICE package حاوی نسخه‌های برنامه (و سایر اطلاعات مفید) است.

فرایندها

گزارش‌های اشکال حاوی حجم عظیمی از داده‌های مربوط به فرایندها است، ازجمله زمان شروع و توقف، طول زمان اجرا، سرویس‌های مرتبط، امتیاز oom_adj، و غیره. برای جزئیات مربوط به نحوه مدیریت فرایندها در Android، به فرایندها و رشته‌ها مراجعه کنید.

تعیین زمان اجرای فرایند

بخش procstats حاوی آمار کامل درباره مدت زمان اجرای فرایندها و سرویس‌های مرتبط است. برای خلاصه سریع و قابل‌خواندن توسط انسان، AGGREGATED OVER را جستجو کنید تا داده‌های سه یا ۲۴ ساعت گذشته را ببینید، سپس Summary: را جستجو کنید تا فهرست فرایندها، مدت زمان اجرای این فرایندها با اولویت‌های مختلف، و استفاده از RAM آن‌ها را با قالب حداقل-میانگین-حداکثر PSS/حداقل-میانگین-حداکثر USS ببینید.

دلایل اجرای فرایند

بخش dumpsys activity processes همه فرایندهای درحال اجرا را براساس امتیاز oom_adj فهرست می‌کند (Android اهمیت فرایند را با اختصاص دادن مقدار oom_adj به فرایند نشان می‌دهد، که ActivityManager می‌تواند آن را به‌طور پویا به‌روزرسانی کند). خروجی مشابه خروجی عکس آنی حافظه است اما حاوی اطلاعات تکمیلی درباره علت اجرای فرایند است. در مثال زیر، ورودی‌های پررنگ نشان می‌دهند که فرایند gms.persistent با اولویت vis (نمایان) درحال اجرا است زیرا فرایند سیستم به NetworkLocationService آن محدود شده است.

اسکن‌ها

برای شناسایی برنامه‌هایی که اسکن‌های «بلوتوث کم‌مصرف» (BLE) بیش‌ازحد انجام می‌دهند، از مراحل زیر استفاده کنید:

  • یافتن پیام‌های گزارش برای BluetoothLeScanner:
    $ grep 'BluetoothLeScanner' ~/downloads/bugreport.txt
    07-28 15:55:19.090 24840 24851 D BluetoothLeScanner: onClientRegistered() - status=0 clientIf=5
    
  • ‫PID را در پیام‌های گزارش پیدا کنید. در این مثال، «24840» و «24851» شناسه فرایند (PID) و شناسه رشته (TID) هستند.
  • برنامه مرتبط با PID را پیدا کنید:
    PID #24840: ProcessRecord{4fe996a 24840:com.badapp/u0a105}
    

    در این مثال، نام بسته com.badapp است.

  • نام بسته را در Google Play جستجو کنید تا برنامه مسئول را شناسایی کنید: https://play.google.com/store/apps/details?id=com.badapp.

توجه: برای دستگاه‌های دارای Android نسخه ۷.۰، سیستم داده‌های مربوط به اسکن‌های BLE را جمع‌آوری می‌کند و این فعالیت‌ها را به برنامه آغازگر منسوب می‌کند. برای جزئیات، به کم‌مصرف (LE) و اسکن‌های بلوتوث مراجعه کنید.