عیب یابی Crashlytics و سوالات متداول


این صفحه راهنمایی عیب‌یابی و پاسخ‌هایی به سؤالات متداول درباره استفاده از Crashlytics ارائه می‌دهد. اگر چیزی را که به دنبالش هستید پیدا نکردید یا به کمک بیشتری نیاز دارید، با پشتیبانی Firebase تماس بگیرید.

عیب یابی عمومی/سؤالات متداول

ممکن است متوجه دو قالب مختلف برای مشکلات فهرست شده در جدول مشکلات خود در کنسول Firebase شوید. و همچنین ممکن است در برخی از مشکلات خود متوجه ویژگی به نام "Variants" شوید. در اینجا دلیل آن است!

در اوایل سال 2023، موتور تجزیه و تحلیل بهبود یافته ای را برای گروه بندی رویدادها و همچنین طراحی به روز شده و برخی ویژگی های پیشرفته برای مسائل جدید (مانند انواع!) ارائه کردیم. برای همه جزئیات، پست اخیر وبلاگ ما را بررسی کنید، اما می توانید برای نکات مهم در زیر بخوانید.

Crashlytics همه رویدادهای برنامه شما (مانند خرابی‌ها، موارد غیرمرگبار و ANR) را تجزیه و تحلیل می‌کند و گروه‌هایی از رویدادها به نام مسائل ایجاد می‌کند — همه رویدادها در یک شماره یک نقطه شکست مشترک دارند.

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

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

در اینجا چیزی است که با این بهبودها تجربه خواهید کرد:

  • ابرداده اصلاح شده در ردیف شماره نمایش داده می شود
    اکنون درک و تریاژ مسائل در برنامه شما آسان تر شده است.

  • مسائل تکراری کمتر
    تغییر شماره خط منجر به مشکل جدیدی نمی شود.

  • اشکال زدایی آسانتر مسائل پیچیده با دلایل ریشه ای مختلف
    از انواع برای اشکال زدایی رایج ترین ردیابی پشته در یک شماره استفاده کنید.

  • هشدارها و سیگنال های معنی دار تر
    یک شماره جدید در واقع نشان دهنده یک باگ جدید است.

  • جستجوی قدرتمندتر
    هر شماره حاوی فراداده قابل جستجوی بیشتری است، مانند نوع استثنا و نام بسته.

در اینجا نحوه اجرای این بهبودها آمده است:

  • وقتی رویدادهای جدیدی را از برنامه شما دریافت می‌کنیم، بررسی می‌کنیم که آیا آنها با مشکل موجود مطابقت دارند یا خیر.

  • اگر مطابقت وجود نداشته باشد، به طور خودکار الگوریتم گروه‌بندی رویداد هوشمندانه‌تر خود را در رویداد اعمال می‌کنیم و یک مشکل جدید با طراحی ابرداده اصلاح‌شده ایجاد می‌کنیم.

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

اگر معیارهای بدون خرابی (مانند کاربران و جلسات بدون خرابی) و/یا هشدارهای سرعت را نمی‌بینید، مطمئن شوید که ازCrashlytics SDK v18.6.0+ (یا Firebase BoM v32.6.0+).

اگر گزارش‌های خرده نان را نمی‌بینید، توصیه می‌کنیم پیکربندی برنامه خود را برای Google Analytics بررسی کنید. مطمئن شوید که شرایط زیر را دارید:

Crashlytics از گزارش ANR برای برنامه‌های Android از دستگاه‌هایی که Android 11 و بالاتر را اجرا می‌کنند، پشتیبانی می‌کند. API اصلی که برای جمع‌آوری ANR استفاده می‌کنیم ( getHistoricalProcessExitReasons ) قابل اعتمادتر از SIGQUIT یا رویکردهای مبتنی بر نظارت است. این API فقط در دستگاه‌های Android 11 و بالاتر در دسترس است.

اگر برخی از ANR های شما BuildId خود را ندارند، به شرح زیر عیب یابی کنید:

  • مطمئن شوید که از نسخه به‌روز Crashlytics Android SDK و Crashlytics Gradle استفاده می‌کنید.

    اگر BuildId s برای اندروید 11 و برخی از ANR های اندروید 12 را ندارید، احتمالاً از یک SDK، پلاگین Gradle یا هر دو قدیمی استفاده می کنید. برای جمع آوری صحیح BuildId برای این ANR ها، باید از نسخه های زیر استفاده کنید:

    • Crashlytics Android SDK نسخه 18.3.5+ ( Firebase BoM نسخه 31.2.2+)
    • پلاگین Crashlytics Gradle نسخه 2.9.4+
  • بررسی کنید که آیا از یک مکان غیر استاندارد برای کتابخانه های مشترک خود استفاده می کنید.

    اگر فقط BuildId را برای کتابخانه‌های مشترک برنامه‌تان از دست داده‌اید، احتمالاً از مکان استاندارد و پیش‌فرض برای کتابخانه‌های مشترک استفاده نمی‌کنید. اگر اینطور باشد، ممکن است Crashlytics نتواند BuildId مرتبط را پیدا کند. توصیه می کنیم از مکان استاندارد برای کتابخانه های مشترک استفاده کنید.

  • مطمئن شوید که BuildId ها را در طول فرآیند ساخت حذف نمی کنید.

    توجه داشته باشید که نکات عیب‌یابی زیر هم برای خرابی‌های ANR و هم برای خرابی‌های بومی اعمال می‌شود.

    • با اجرای readelf -n روی باینری های خود بررسی کنید که آیا BuildId وجود دارد یا خیر. اگر BuildId وجود ندارد، سپس -Wl,--build-id به پرچم‌های سیستم ساخت خود اضافه کنید.

    • بررسی کنید که در تلاش برای کاهش اندازه APK خود، BuildId ها را ناخواسته حذف نکنید.

    • اگر نسخه‌های stripped و unstripped یک کتابخانه را نگه می‌دارید، حتماً به نسخه صحیح در کد خود اشاره کنید.

ممکن است بین تعداد ANR بین Google Play و Crashlytics ناهماهنگی وجود داشته باشد. این به دلیل تفاوت در مکانیسم جمع آوری و گزارش داده های ANR انتظار می رود. Crashlytics هنگام راه‌اندازی بعدی برنامه، ANR را گزارش می‌کند، در حالی که Android Vitals داده‌های ANR را پس از وقوع ANR ارسال می‌کند.

علاوه بر این، Crashlytics فقط ANR‌هایی را که در دستگاه‌های دارای Android نسخه ۱۱ و بالاتر رخ می‌دهند، در مقایسه با Google Play که ANR‌های دستگاه‌های دارای سرویس‌های Google Play و رضایت جمع‌آوری داده‌ها را نشان می‌دهد، نمایش می‌دهد.

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

  • اگر از پیوند دهنده lld از زنجیره ابزار LLVM استفاده می کنید، اضافه کنید:

    -Wl,--no-rosegment
  • اگر از پیوند دهنده ld.gold از زنجیره ابزار گنو استفاده می کنید، اضافه کنید:

    -Wl,--rosegment

اگر همچنان ناهماهنگی های stack trace را مشاهده می کنید (یا اگر هیچ کدام از پرچم ها مربوط به زنجیره ابزار شما نیست)، به جای آن موارد زیر را به فرآیند ساخت خود اضافه کنید:

-fno-omit-frame-pointer

پلاگین Crashlytics یک تولید کننده فایل نماد Breakpad سفارشی را بسته بندی می کند. اگر ترجیح می‌دهید از باینری خود برای تولید فایل‌های نماد Breakpad استفاده کنید (به عنوان مثال، اگر ترجیح می‌دهید همه فایل‌های اجرایی بومی در زنجیره ساخت خود را از منبع بسازید)، از ویژگی انتخابی پسوند symbolGeneratorBinary برای تعیین مسیر فایل اجرایی استفاده کنید.

می توانید مسیر دودویی تولید کننده فایل نماد Breakpad را به یکی از دو روش مشخص کنید:

  • گزینه 1 : مسیر را از طریق پسوند firebaseCrashlytics در فایل build.gradle خود مشخص کنید.

    موارد زیر را به فایل build.gradle.kts در سطح برنامه خود اضافه کنید:

    android {
      buildTypes {
        release {
          configure<CrashlyticsExtension> {
            nativeSymbolUploadEnabled = true
            // Add these optional fields to specify the path to the executable
            symbolGeneratorType = "breakpad"
            breakpadBinary = file("/PATH/TO/BREAKPAD/DUMP_SYMS")
          }
        }
      }
    }
    android {
      // ...
      buildTypes {
        // ...
        release {
          // ...
          firebaseCrashlytics {
            // existing; required for either symbol file generator
            nativeSymbolUploadEnabled true
            // Add this optional new block to specify the path to the executable
            symbolGenerator {
              breakpad {
                binary file("/PATH/TO/BREAKPAD/DUMP_SYMS")
              }
            }
          }
       }
    }
  • گزینه 2 : مسیر را از طریق یک خط ویژگی در فایل ویژگی های Gradle خود مشخص کنید

    می توانید از ویژگی com.google.firebase.crashlytics.breakpadBinary برای تعیین مسیر فایل اجرایی استفاده کنید.

    شما می توانید به صورت دستی فایل ویژگی های Gradle خود را به روز کنید یا فایل را از طریق خط فرمان به روز کنید. به عنوان مثال، برای تعیین مسیر از طریق خط فرمان، از دستوری مانند زیر استفاده کنید:

    ./gradlew -Pcom.google.firebase.crashlytics.symbolGenerator=breakpad \
      -Pcom.google.firebase.crashlytics.breakpadBinary=/PATH/TO/BREAKPAD/DUMP_SYMS \
      app:assembleRelease app:uploadCrashlyticsSymbolFileRelease
    

اگر استثنای زیر را مشاهده کردید، احتمالاً از نسخه‌ای از DexGuard استفاده می‌کنید که با Firebase Crashlytics SDK ناسازگار است:

java.lang.IllegalArgumentException: Transport backend 'cct' is not registered

این استثنا برنامه شما را خراب نمی‌کند، اما از ارسال گزارش‌های خرابی جلوگیری می‌کند. برای رفع این مشکل:

  1. مطمئن شوید که از آخرین نسخه DexGuard 8.x استفاده می کنید. آخرین نسخه حاوی قوانینی است که توسط Firebase Crashlytics SDK مورد نیاز است.

  2. اگر نمی خواهید نسخه DexGuard خود را تغییر دهید، سعی کنید خط زیر را به قوانین مبهم سازی خود (در فایل پیکربندی DexGuard خود) اضافه کنید:

    -keepresourcexmlelements manifest/application/service/meta-data@value=cct

هنگامی که یک برنامه از یک مبهم کننده استفاده می کند که پسوند فایل را نشان نمی دهد، Crashlytics به طور پیش فرض هر مشکل را با پسوند فایل .java ایجاد می کند.

برای اینکه Crashlytics بتواند مشکلاتی با پسوند فایل درست ایجاد کند، مطمئن شوید که برنامه شما از تنظیمات زیر استفاده می‌کند:

  • از اندروید Gradle 4.2.0 یا بالاتر استفاده می کند
  • از R8 با مبهم سازی روشن استفاده می کند. برای به روز رسانی برنامه خود به R8، این مستندات را دنبال کنید.

توجه داشته باشید که پس از به‌روزرسانی به تنظیماتی که در بالا توضیح داده شد، ممکن است مشکلات .kt جدید را مشاهده کنید که تکراری از مشکلات .java موجود هستند. برای کسب اطلاعات بیشتر در مورد آن شرایط ، پرسش‌های متداول را ببینید.

از اواسط دسامبر 2021، Crashlytics پشتیبانی از برنامه‌هایی را که از Kotlin استفاده می‌کنند، بهبود بخشید.

تا همین اواخر، مبهم‌کننده‌های موجود پسوند فایل را آشکار نمی‌کردند، بنابراین Crashlytics به طور پیش‌فرض هر مشکل را با پسوند فایل .java ایجاد می‌کرد. با این حال، از اندروید Gradle 4.2.0، R8 از پسوندهای فایل پشتیبانی می کند.

با این به‌روزرسانی، Crashlytics اکنون می‌تواند تعیین کند که آیا هر کلاسی که در برنامه استفاده می‌شود در Kotlin نوشته شده است یا خیر و نام فایل صحیح را در امضای شماره قرار دهد. اگر برنامه شما دارای تنظیمات زیر باشد، خرابی‌ها اکنون به درستی به فایل‌های .kt نسبت داده می‌شوند (در صورت لزوم):

  • برنامه شما از Android Gradle 4.2.0 یا بالاتر استفاده می کند.
  • برنامه شما از R8 با مبهم سازی روشن استفاده می کند.

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

یادداشت‌ها به اعضای پروژه اجازه می‌دهند تا در مورد مسائل خاص با سؤالات، به‌روزرسانی وضعیت و غیره نظر دهند.

هنگامی که یک عضو پروژه یادداشتی را پست می کند، با ایمیل حساب Google خود برچسب گذاری می شود. این آدرس ایمیل همراه با یادداشت برای همه اعضای پروژه که به مشاهده یادداشت دسترسی دارند قابل مشاهده است.

موارد زیر دسترسی مورد نیاز برای مشاهده، نوشتن و حذف یادداشت ها را شرح می دهد:

به درک معیارهای بدون خرابی مراجعه کنید.

یادداشت‌ها به اعضای پروژه اجازه می‌دهند تا در مورد مسائل خاص با سؤالات، به‌روزرسانی وضعیت و غیره نظر دهند.

هنگامی که یک عضو پروژه یادداشتی را پست می کند، با ایمیل حساب Google خود برچسب گذاری می شود. این آدرس ایمیل همراه با یادداشت برای همه اعضای پروژه که به مشاهده یادداشت دسترسی دارند قابل مشاهده است.

موارد زیر دسترسی مورد نیاز برای مشاهده، نوشتن و حذف یادداشت ها را شرح می دهد:

ادغام ها

اگر پروژه شما از Crashlytics در کنار Google Mobile Ads SDK استفاده می کند، احتمالاً گزارشگران خرابی هنگام ثبت کنترل کننده های استثنا دخالت می کنند. برای رفع مشکل، با تماس با disableSDKCrashReporting ، گزارش خرابی را در SDK Mobile Ads خاموش کنید.

پس از اینکه Crashlytics به BigQuery پیوند دادید، مجموعه داده‌های جدیدی که ایجاد می‌کنید به‌طور خودکار در ایالات متحده قرار می‌گیرند، بدون در نظر گرفتن مکان پروژه Firebase شما.

پشتیبانی از پلتفرم

Firebase Crashlytics NDK از ARMv5 (armeabi) پشتیبانی نمی کند. پشتیبانی از این ABI از NDK r17 حذف شد.

مسائل پسرفته

زمانی که شما قبلاً آن را بسته اید، یک مشکل پسرفت داشته است، اما Crashlytics گزارش جدیدی دریافت می کند مبنی بر اینکه مشکل دوباره رخ داده است. Crashlytics به طور خودکار این مشکلات پسرفته را مجدداً باز می کند تا بتوانید آنها را مطابق با برنامه خود برطرف کنید.

در اینجا یک سناریوی مثال آمده است که توضیح می دهد چگونه Crashlytics یک موضوع را به عنوان یک رگرسیون طبقه بندی می کند:

  1. برای اولین بار، Crashlytics یک گزارش خرابی در مورد Crash "A" دریافت می کند. Crashlytics یک مشکل مربوط به آن خرابی را باز می کند (مساله "A").
  2. شما این اشکال را به سرعت برطرف می‌کنید، شماره A را می‌بندید و سپس نسخه جدیدی از برنامه خود را منتشر می‌کنید.
  3. Crashlytics پس از بسته شدن این موضوع، گزارش دیگری در مورد مشکل "A" دریافت می کند.
    • اگر گزارش مربوط به نسخه برنامه‌ای است که Crashlytics هنگام بستن مشکل از آن مطلع بوده است (به این معنی که نسخه اصلاً گزارش خرابی را برای هر خرابی ارسال کرده است)، Crashlytics این مشکل را پسرفته در نظر نخواهد گرفت. موضوع بسته خواهد ماند.
    • اگر گزارش مربوط به نسخه برنامه‌ای است که Crashlytics از آن اطلاعی نداشته است (به این معنی که این نسخه هرگز هیچ گزارش خرابی برای هر خرابی ارسال نکرده است)، Crashlytics مشکل را پسرفته در نظر می‌گیرد و دوباره آن را باز می‌کند.

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

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

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

اگر به دلیل الگوریتم رگرسیون ما نمی خواهید مشکلی دوباره باز شود، به جای بستن آن، آن را "بی صدا" کنید.