How to make sense of Android crash logs | Bugsnag Blog

文章推薦指數: 80 %
投票人數:10人

If an app hasn't got a crash reporting SDK installed, then the next best method for retrieving crash logs is to use adb to view logcat. This is ... ProductFeaturesStabilityManagementStabilityScoreSearch& SegmentOn-PremiseIntegrationsEnterpriseSupportSecurityPlatformsAndroidiOSJavaScriptPythonReactNativeUnityBrowseallplatformsFeaturedcustomersLyftutilizestwo-waysyncintegrationstoshipnewproductfeatures40%fasterChimereducescrashratebymonitoringwithBugsnagSeeallcustomersSolutionsApplicationWebSolutionMobileSolutionServer-SideSolutionIndustryBusiness&ConsumerApplicationseCommerceFinancialServicesGamingHealthTechnologyMedia&EntertainmentEngineeringfocusSoftwareTeamsObservabilityTeamsReleaseManagementEngineeringManagementCompareBugsnagvs.FirebaseBugsnagvs.APMToolsBugsnagvs.ErrorLoggingBugsnagvs.HomegrownMonitoringPricingResourcesLearnResourceLibraryBlogWebinarsCustomerStoriesConnectEventsApps+CoffeeConnectionContactBugsnagFeaturedReadsBlogProgressivedelivery:accelerateappreleaseswhileminimizingbugsReadmoreReportApplicationStabilityIndex:CharacteristicsofLeadingMobileAppsReadmoreDocsSigninGetStartedRequestademoDashboardBlog/EngineeringJamieLynchNoitemsfound.JamieLynchSeptember18,2019/17minHowtomakesenseofAndroidcrashlogsSharethispost:AndroidCrashLogErrors:ExplainedCrashesonAndroidcanbeimmenselyfrustratingforusers,somuchsothatafterexperiencingaslittleastwocrashes,thetypicaluserwilluninstallyourapp.Fortunately,theAndroidFrameworkprovidessomegreattoolsfordebuggingcrashes,andprovidesseveralusefulcrashlogsthatdeveloperscanreadtodeterminewhatcausedthatcriticalissue.Inthisblogpostwe’llcoverthethreemostimportantcrashlogsusedbythesystem:exceptionstacktraces,ANRtraces,andNDKtombstones.ExceptionStacktraceJVMstacktracesarethemostcommontypeofcrashthattypicalAndroidapplicationswillencounter,asthemajorityofappsarewrittenineitherKotlinorJava.InJVMlanguages,anExceptionisthrowninexceptionalcircumstances,andcontainsdebuginformationabouttheerrorconditionthatwentwrong,suchasastacktracewithfile/linenumberinformation,andanerrormessage.Ifanapphasn’tgotacrashreportingSDKinstalled,thenthenextbestmethodforretrievingcrashlogsistouseadbtoviewlogcat.Thisisaconvenientmethodifphysicalaccesstothedeviceisanoption,becausethedefaultUncaughtExceptionHandlerinAndroidappsprintsouttheentirestacktracetoLogcatbeforeterminatingtheprocess,meaningthecrashiseffectivelyloggedouttoanaccessiblelocationfordevelopers.ANRTraceANRs(ApplicationNotResponding)occurwhenanapplicationdoesnotrespondtouserinputforanoticeableperiodoftime.Thevisibleeffectofthisisthatanapphas‘frozen’fromauser’sperspective,whichcanbeimmenselyfrustrating.Commoncausesincludeperformingdiskreads/writesonthemainthread,andotherlong-runningtasks,whichpreventstheUserInterfacefromupdatinginresponsetouserinput.Iftheappisintheforeground,afterapproximately5secondsadialogwillbeshownwhichallowstheusertokilltheapp.AtthispointatraceincludingdetailsoftheANRwillbewrittentodisk,fromwhichvaluableinformationfordebuggingcanberetrieved.Again,thisrequiresphysicalaccesstothedeviceunlessyouhaveacrashreportingSDKinstalledthatsupportsANRdetection.TombstoneTombstonecrashlogsarewrittenwhenanativecrashinC/C++codeoccursinanAndroidapplication.TheAndroidplatformwritesatraceofalltherunningthreadsatthetimeofthecrashto/data/tombstones,alongwithadditionalinformationfordebugging,suchasinformationaboutmemoryandopenfiles.Tombstonesaretheclosesttothemetalintermsofinformation,astheywillrecorddetailssuchasrawmemoryaddresses,andassuchcanbeabittrickiertounderstandunlessyou’refamiliarwithdebuggingnativecode.Again,tombstonesrequirephysicalaccesstoarooteddeviceinordertoberead.HowtogetCrashLogsfromanAndroiddeviceAsaprerequisitetoallthesesteps,youshouldhaveinstalledAndroidStudioandaddedthecommandlinetoolstoyourpath.Theselocalmethodsmakeuseoftheadbtool.Youshouldalsohaveadeviceoremulatorconnectedwhichhashaddeveloperoptionsenabled.Note:ifyouarecomfortableusingtheDeviceFileExplorerinAndroidStudiodirectly,youcanopendevicefilesdirectlyfromthereratherthanusingadbpull.ExceptionStacktraceBydefault,exceptionstacktracesareprintedouttotheLogcattoolonAndroiddevices.Itispossibletoretrievecrashlogsviathefollowingsteps:Runthefollowingcommand--CODElanguage-shell--adblogcatAndroidRuntime:E*:STriggeracrashonthedevice.Thestacktracewillshowupasnewtextintheterminal.SavetheterminaloutputtoafileofyourchoiceforinspectionlaterIfacrashhasoccurredrecentlyonthedevice,youcanskipstep2.ThisisbecauseLogcatretainsabufferofrecentlogswhichshouldincludetheexception.Thisistimesensitivehowever-soifyou’relookingforacrashfromadayago,thatinformationmaybegoneforeverunlessyouuseacrashreportingtoolsuchasBugsnag.ANRTraceTriggeranANRonthedevice.Runthefollowingcommand,replacingthedestinationwithafileofyourchoice--CODElanguage-shell--adbpull/data/anr/traces.txtInspecttheinformationintheANRcrashlogbyopeningthesavedfileAlternatively,youcaninspectsummaryANRinformationbyrunningthefollowingcommand--CODElanguage-shell--adblogcatActivityManager:E*:STombstoneRootyourdeviceoremulatorsothatyoucanaccessthetombstonedirectory.(Bewarewhenrootingdevices,asthisstepcanpotentiallybrickyourphone)Triggeranativecrashonthedevice.Runthefollowingcommandtodeterminewhattombstonecrashlogsarepresentonthedevice--CODElanguage-shell--adbls/data/tombstonesRunthefollowingcommand,replacingthedestinationwithafileofyourchoice.tombstone_01isshownasanexamplefilenamehere,thatwouldbeobtainedinthepreviousstep--CODElanguage-shell--adbpull/data/tombstones/tombstone_01InspecttheinformationintheTombstonecrashlogbyopeningthesavedfileMakingsenseofAndroidCrashLogDataExceptionStacktraceReadingaJVMstacktracecanbeintimidatingatfirst,butbybreakingitdownintoitsconstituentpartsthetaskbecomesfairlyeasy.Let’swalkthroughitstepbystep,withthefollowingRuntimeExceptionthathasbeenthrowninanexampleapplication:--CODElanguage-shell--2019-08-2716:10:28.30310773-10773/com.bugsnag.android.exampleE/AndroidRuntime:FATALEXCEPTION:main  Process:com.bugsnag.android.example,PID:10773  java.lang.RuntimeException:FatalCrash    atcom.example.foo.CrashyClass.sendMessage(CrashyClass.java:10)    atcom.example.foo.CrashyClass.crash(CrashyClass.java:6)    atcom.bugsnag.android.example.ExampleActivity.crashUnhandled(ExampleActivity.kt:55)    atcom.bugsnag.android.example.ExampleActivity$onCreate$1.invoke(ExampleActivity.kt:33)    atcom.bugsnag.android.example.ExampleActivity$onCreate$1.invoke(ExampleActivity.kt:14)    atcom.bugsnag.android.example.ExampleActivity$sam$android_view_View_OnClickListener$0.onClick(ExampleActivity.kt)    atandroid.view.View.performClick(View.java:5637)    atandroid.view.View$PerformClick.run(View.java:22429)    atandroid.os.Handler.handleCallback(Handler.java:751)    atandroid.os.Handler.dispatchMessage(Handler.java:95)    atandroid.os.Looper.loop(Looper.java:154)    atandroid.app.ActivityThread.main(ActivityThread.java:6119)    atjava.lang.reflect.Method.invoke(NativeMethod)    atcom.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)    atcom.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)Thefirstplacetostartistowardsthetopofourcrashlog.HerewecanseetheprocessIDthatthesystemassignedtheexecutingapp,alongwiththepackagename,whichcanbeusefulwhencorrelatingagainstotherinformationobtainedvialogcat.Inourexampleapp,thepackagenameis“com.bugsnag.android.example”:--CODElanguage-shell--Process:com.bugsnag.android.example,PID:10773Thenextusefulpieceofinformationistheexceptionclass.InJava/Kotlin,allexceptionsanderrorsareclasseswhichextendThrowableoroneofThrowable’ssubclasses,andeachexceptionclasscanhaveadifferentsemanticmeaning.Forexample,adevelopermaywishtothrowanIllegalStateExceptioniftheprogramenteredanunexpectedstate,oranIllegalArgumentExceptionifauserattemptedtosavenullastheirname.Inourcase,we’vethrownaRuntimeException,whosefullyqualifiedclassnameisdisplayedbelow:--CODElanguage-shell--java.lang.RuntimeException:FatalCrashTheerrormessageisalsoprintedtothecrashlog,whichcanbeveryusefulforprovidingadditionaldebuginformation.Inourcase,wehavejustsuppliedthetext“FatalCrash”,butwecouldequallypassthevaluesofourvariablesatthetimeofthecrashifwewantedfurtherinformationfordebugging.Thenextthinginourcrashlogisthejuicypartoftheinformation-astacktraceofthethreadwheretheexceptionoccurred.Lookingatthetopstackframewillusuallyallowustofindexactlywheretheerrorwasthrownfrom,andtheframesbelowitwillallowustoobservewhattheprogramstatewasatthetimeofthecrash.Thetopstackframeisthefollowing:--CODElanguage-shell--com.example.foo.CrashyClass.sendMessage(CrashyClass.java:10)Wecanimmediatelyseethatthiscontainssomeveryusefulinformation.Wearegiventheclass,“com.example.foo.CrashyClass”,sowecanopenthesourcefileandhuntforabugthere.We’realsogiventhemethodname,“sendMessage”,andthelinenumberofthecrash,10,sowecanpinpointexactlyinoursourcewheretheexceptionwasthrownfrom.Understandingthecrashlogfromthispointonwardsisacaseofreadingthestackframesbelow,whichareintheorderinwhichthemethodswereoriginallycalled.Considertheexamplebelow:--CODElanguage-shell--atcom.example.foo.CrashyClass.sendMessage(CrashyClass.java:10)    atcom.example.foo.CrashyClass.crash(CrashyClass.java:6)    atcom.bugsnag.android.example.ExampleActivity.crashUnhandled(ExampleActivity.kt:55)Startingatthetop,wecantellthat“sendMessage”wasinvokedby“crash”,whichwasinturninvokedbyamethodnamed“crashUnhandled”,whichappearstobetheoriginofourcrash.Ofcourse,thefullexceptionstacktracewassomewhatmorecomplex,andalsoinvolvedmethodcallsintheAndroidframework,butthebasicprincipleremainsthesame.Animportantnoteisthatinproduction,appsareoftenobfuscatedbytoolssuchasProguardwhichcanmeantheoriginalsymbolsarenotpresent,andthestacktracebecomesunintelligible.Fortunately,mostcrashreportingservicesprovidepluginsthatautomaticallyuploadamappingfilethatcontainstheinformationnecessarytosymbolicatecrashreportsfromyourproductionapps.ANRTraceANRtracescontainaverylargeamountofinformation.AsanANRcanpotentiallybecausedbymultipleappscontendingforalimitednumberofresources,thefullcrashlogcontainsstacktracesformultipledifferentprocesses.Thisfullinformationcanbeveryusefulfordebuggingwhenallelsefails,butmostofthetimethesummaryANRinformationprintedintoLogcatissufficienttodebugtheerror.Considerthefollowing:--CODElanguage-shell--2019-08-2716:12:57.3011717-1733/system_processE/ActivityManager:ANRincom.bugsnag.android.example(com.bugsnag.android.example/.ExampleActivity)  PID:10859  Reason:Inputdispatchingtimedout(Waitingtosendnon-keyeventbecausethetouchedwindowhasnotfinishedprocessingcertaininputeventsthatweredeliveredtoitover500.0msago. Waitqueuelength:33. Waitqueueheadage:6178.1ms.)  Load:0.32/0.62/0.37  CPUusagefrom323086msto-1msago(2019-08-2713:16:43.467to2019-08-2716:12:54.131):   5.7%1717/system_server:2.6%user+3%kernel/faults:21251minor   4.7%10392/com.bugsnag.android.example:1.3%user+3.3%kernel/faults:587minor   3.9%2375/com.google.android.gms:2.9%user+0.9%kernel/faults:71377minor51major   3.1%16/ksoftirqd/2:0%user+3.1%kernel   2.5%2254/com.google.android.googlequicksearchbox:search:1.1%user+1.4%kernel/faults:10193minor   1.2%10427/kworker/u8:0:0%user+1.2%kernel   0.9%8990/kworker/u8:2:0%user+0.9%kernel   0.8%1342/surfaceflinger:0.1%user+0.7%kernel/faults:35minor   0.5%1344/adbd:0%user+0.4%kernel/faults:8471minor   0.4%1896/com.google.android.gms.persistent:0.3%user+0%kernel/faults:1106minor   0.4%1288/logd:0.1%user+0.3%kernel/faults:43minor   0.3%1806/com.android.systemui:0.2%user+0%kernel/faults:404minor   0.2%1916/com.android.phone:0.1%user+0%kernel/faults:203minor   0.2%1410/audioserver:0%user+0.1%kernel/faults:119minor   0.1%10429/kworker/u8:3:0%user+0.1%kernel   0.1%10378/com.google.android.apps.photos:0.1%user+0%kernel/faults:426minor   0.1%8/rcu_preempt:0%user+0.1%kernel   0%1396/jbd2/dm-0-8:0%user+0%kernel   0%2179/com.google.android.apps.nexuslauncher:0%user+0%kernel/faults:802minor1major   0%1409/zygote:0%user+0%kernel/faults:857minor   0%3951/com.android.defcontainer:0%user+0%kernel/faults:265minor   0%10137/kworker/u9:0:0%user+0%kernel   0%1987/wpa_supplicant:0%user+0%kernel   0%10205/com.google.android.apps.docs:0%user+0%kernel/faults:50minor   0%1378/dmcrypt_write:0%user+0%kernel   0%2111/com.google.process.gapps:0%user+0%kernel/faults:356minor   0%3882/com.android.printspooler:0%user+0%kernel/faults:241minor   0%8829/kworker/u9:2:0%user+0%kernel   0%9808/kworker/u9:4:0%user+0%kernel   0%19/migration/3:0%user+0%kernel   0%1420/rild:0%user+0%kernel   0%10138/kworker/u9:1:0%user+0%kernel   0%1339/lmkd:0%user+0%kernel   0%1419/netd:0%user+0%kernel/faults:59minor   0%1793/com.android.inputmethod.latin:0%user+0%kernel/faults:12minor   0%10146/com.android.gallery3d:0%user+0%kernel/faults:95minor   0%10181/android.process.acore:0%user+0%kernel/faults:52minor   0%1281/kworker/0:1H:0%user+0%kernel   0%10162/kworker/2:1:0%user+0%kernel   0%10348/com.google.android.partnersetup:0%user+0%kernel/faults:92minor   0%20/ksoftirqd/3:0%user+0%kernel   0%10308/android.process.media:0%user+0%kernel/faults:16minor   0%1336/healthd:0%user+0%kernel   0%1354/logcat:0%user+0%kernel   0%1709/hostapd:0%user+0%kernel   0%3/ksoftirqd/0:0%user+0%kernel   0%1341/servicemanager:0%user+0%kernel   0%2091/com.google.android.ext.services:0%user+0%kernel/faults:10minor   0%10475/com.google.android.apps.photos:CameraShortcut:0%user+0%kernel/faults:29minor   0%4/kworker/0:0:0%user+0%kernel   0%12/ksoftirqd/1:0%user+0%kernel   0%1422/fingerprintd:0%user+0%kernel   0%1591/dhcpclient:0%user+0%kernel   0%1706/ipv6proxy:0%user+0%kernel   0%1913/sdcard:0%user+0%kernel   0%2137/com.google.android.googlequicksearchbox:interactor:0%user+0%kernel/faults:3minor   0%687/kworker/1:1:0%user+0%kernel   0%1297/vold:0%user+0%kernel/faults:10minor   0%1413/installd:0%user+0%kernel/faults:35minor   0%1//init:0%user+0%kernel   0%11/migration/1:0%user+0%kernel   0%466Firstoff,thecrashlogcontainsinformationaboutwhichprocessonthesystemsufferedanANR,andgivestheprocessIDandpackagename,whichcomesinusefulwhenfindingtheappropriatestacktracesinthemoredetailedANRtrace:--CODElanguage-shell--E/ActivityManager:ANRincom.bugsnag.android.example(com.bugsnag.android.example/.ExampleActivity)  PID:10859TheAndroidframeworkgivesusareasonfortheANR.Inthiscase,theusertouchedthescreenseveraltimes,andthedispatchqueuewaitedforover6secondswithoutshowingavisibleresponsetothesetouchevents.Thisrepresentsaverybaduserexperiencethatwouldbenoticeableasthewholeappwouldappeartofreezefromauser’sperspective:--CODElanguage-shell--Reason:Inputdispatchingtimedout(Waitingtosendnon-keyeventbecausethetouchedwindowhasnotfinishedprocessingcertaininputeventsthatweredeliveredtoitover500.0msago.Waitqueuelength:33.Waitqueueheadage:6178.1ms.)Finally,we’regivensomeCPUloadinformation.WhilesomeANRshavesimplecausessuchasperformingIOonthemainthread,thisisnotalwaysthecase.SometimesanANRcanoccuronalow-enddeviceduetoalotofresource-hungryappscompetingforCPU,sodeterminingwhetherthereareotherappsusinglotsofresourcesatthesametimeasourapplicationcanbeveryhelpful:--CODElanguage-shell--CPUusagefrom323086msto-1msago(2019-08-2713:16:43.467to2019-08-2716:12:54.131):   5.7%1717/system_server:2.6%user+3%kernel/faults:21251minor   4.7%10392/com.bugsnag.android.example:1.3%user+3.3%kernel/faults:587minor   3.9%2375/com.google.android.gms:2.9%user+0.9%kernel/faults:71377minor51major   3.1%16/ksoftirqd/2:0%user+3.1%kernel   2.5%2254/com.google.android.googlequicksearchbox:search:1.1%user+1.4%kernel/faults:10193minorTombstoneLikeANRtraces,tombstonesalsocontainaverylargeamountofinformationthatwouldn’tbepossibletowalkthroughentirely.We’llconsideratruncatedexample,whichshowsthemostimportantinformationnearthetop:--CODElanguage-shell--ABI:'x86'pid:15300,tid:15300,name:android.example >>>com.bugsnag.android.example<<>>com.bugsnag.android.example<<



請為這篇文章評分?