Bu bölümde hata ayıklama için faydalı araçlar ve ilgili komutlar özetlenmiştir. geliştirme sırasında yerel Android platform kodunu takip etme ve profilini çıkarma pek çok farklı işlevi vardır.
Not: Bu bölümdeki ve diğer yerlerdeki sayfalar
ile birlikte adb
kullanımını önermektedir:
Android'in belirli yönlerinde hata ayıklamak için setprop
bağımsız değişkeni.
Android 7.x ve önceki sürümlerde, mülk adlarının uzunluk sınırı 32 ile sınırlıydı.
karakteri ekleyin. Bu, uygulamanın adıyla bir sarmalama özelliği oluşturmak için
ancak sığdırmak için de kısaltmamız gerekti. Android 8.0 ve sonraki sürümlerde bu
sınırı çok daha büyüktür ve kısaltılmamaları gerekir.
Bu sayfada, logcat çıkışında bulunan kilitlenme dökümleriyle ilgili temel bilgiler yer almaktadır.
Başka sayfalarda ise sitenin veya
yerel kilitlenmeleri teşhis etme,
şununla sistem hizmetlerini keşfediyor:
dumpsys
, görüntüleniyor
yerel bellek,
ağ,
ve RAM
kullanımı, belleği tespit etmek için AddressSanitizer
hataları gözden geçirmesi,
Performans sorunları (şunları içerir:
Sistem izleme) oluşturun ve
hata ayıklayıcılar.
Kaza dökümleri ve mezar taşları
Dinamik olarak bağlantılı bir yürütülebilir dosya başlatıldığında, birçok sinyal işleyici
olayda, temel kilitlenme dökümünün logcat'e yazılmasına neden olduğunu bildirmiştir.
ve /data/tombstones/
adresine daha ayrıntılı bir mezarlık dosyası yazılır.
Tombstone, kilitlenen işlemle ilgili ek veriler içeren bir dosyadır. Özellikle de
yığın izlemeleri (stack trace), kilitlenme işlemindeki tüm iş parçacıkları (yalnızca
sinyali), tam bellek haritasını ve tüm açık dosya tanımlayıcılarının listesini içerir.
Android 8.0'dan önceki kilitlenmeler
debuggerd
ve debuggerd64
arka plan programları. Android 8.0 ve sonraki sürümlerde
crash_dump32
ve crash_dump64
gerektiğinde üretildi.
Kilitlenme dökümü yalnızca
unutmayın. Bu, strace
veya GCLID gibi araçları kullanarak
lldb
, kilitlenme dökümlerinin gerçekleşmesini önler.
Örnek çıktı (zaman damgaları ve fazladan bilgiler kaldırılmış olarak):
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** Build fingerprint: 'Android/aosp_angler/angler:7.1.1/NYC/enh12211018:eng/test-keys' Revision: '0' ABI: 'arm' pid: 17946, tid: 17949, name: crasher >>> crasher <<< signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xc r0 0000000c r1 00000000 r2 00000000 r3 00000000 r4 00000000 r5 0000000c r6 eccdd920 r7 00000078 r8 0000461a r9 ffc78c19 sl ab209441 fp fffff924 ip ed01b834 sp eccdd800 lr ecfa9a1f pc ecfd693e cpsr 600e0030 backtrace: #00 pc 0004793e /system/lib/libc.so (pthread_mutex_lock+1) #01 pc 0001aa1b /system/lib/libc.so (readdir+10) #02 pc 00001b91 /system/xbin/crasher (readdir_null+20) #03 pc 0000184b /system/xbin/crasher (do_action+978) #04 pc 00001459 /system/xbin/crasher (thread_callback+24) #05 pc 00047317 /system/lib/libc.so (_ZL15__pthread_startPv+22) #06 pc 0001a7e5 /system/lib/libc.so (__start_thread+34) Tombstone written to: /data/tombstones/tombstone_06
Son çıkış satırı diskteki tüm mezar taşının konumunu verir.
Sadeleştirilmiş ikili kodlarınız varsa daha ayrıntılı
yığınınızı aşağıdaki satır içine yapıştırarak satır numarası bilgileriyle rahatlayın:
development/scripts/stack
:
development/scripts/stack
İpucu: Size kolaylık sağlaması için, lunch
uygulamasını daha önce çalıştırdıysanız
stack
zaten $PATH
cihazınızda olduğundan
tam yol sunar.
Örnek çıkış (yukarıdaki logcat çıkışına göre):
Reading native crash info from stdin 03-02 23:53:49.477 17951 17951 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 03-02 23:53:49.477 17951 17951 F DEBUG : Build fingerprint: 'Android/aosp_angler/angler:7.1.1/NYC/enh12211018:eng/test-keys' 03-02 23:53:49.477 17951 17951 F DEBUG : Revision: '0' 03-02 23:53:49.477 17951 17951 F DEBUG : ABI: 'arm' 03-02 23:53:49.478 17951 17951 F DEBUG : pid: 17946, tid: 17949, name: crasher >>> crasher <<< 03-02 23:53:49.478 17951 17951 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xc 03-02 23:53:49.478 17951 17951 F DEBUG : r0 0000000c r1 00000000 r2 00000000 r3 00000000 03-02 23:53:49.478 17951 17951 F DEBUG : r4 00000000 r5 0000000c r6 eccdd920 r7 00000078 03-02 23:53:49.478 17951 17951 F DEBUG : r8 0000461a r9 ffc78c19 sl ab209441 fp fffff924 03-02 23:53:49.478 17951 17951 F DEBUG : ip ed01b834 sp eccdd800 lr ecfa9a1f pc ecfd693e cpsr 600e0030 03-02 23:53:49.491 17951 17951 F DEBUG : 03-02 23:53:49.491 17951 17951 F DEBUG : backtrace: 03-02 23:53:49.492 17951 17951 F DEBUG : #00 pc 0004793e /system/lib/libc.so (pthread_mutex_lock+1) 03-02 23:53:49.492 17951 17951 F DEBUG : #01 pc 0001aa1b /system/lib/libc.so (readdir+10) 03-02 23:53:49.492 17951 17951 F DEBUG : #02 pc 00001b91 /system/xbin/crasher (readdir_null+20) 03-02 23:53:49.492 17951 17951 F DEBUG : #03 pc 0000184b /system/xbin/crasher (do_action+978) 03-02 23:53:49.492 17951 17951 F DEBUG : #04 pc 00001459 /system/xbin/crasher (thread_callback+24) 03-02 23:53:49.492 17951 17951 F DEBUG : #05 pc 00047317 /system/lib/libc.so (_ZL15__pthread_startPv+22) 03-02 23:53:49.492 17951 17951 F DEBUG : #06 pc 0001a7e5 /system/lib/libc.so (__start_thread+34) 03-02 23:53:49.492 17951 17951 F DEBUG : Tombstone written to: /data/tombstones/tombstone_06 Reading symbols from /huge-ssd/aosp-arm64/out/target/product/angler/symbols Revision: '0' pid: 17946, tid: 17949, name: crasher >>> crasher <<< signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xc r0 0000000c r1 00000000 r2 00000000 r3 00000000 r4 00000000 r5 0000000c r6 eccdd920 r7 00000078 r8 0000461a r9 ffc78c19 sl ab209441 fp fffff924 ip ed01b834 sp eccdd800 lr ecfa9a1f pc ecfd693e cpsr 600e0030 Using arm toolchain from: /huge-ssd/aosp-arm64/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/ Stack Trace: RELADDR FUNCTION FILE:LINE 0004793e pthread_mutex_lock+2 bionic/libc/bionic/pthread_mutex.cpp:515 v------> ScopedPthreadMutexLocker bionic/libc/private/ScopedPthreadMutexLocker.h:27 0001aa1b readdir+10 bionic/libc/bionic/dirent.cpp:120 00001b91 readdir_null+20 system/core/debuggerd/crasher.cpp:131 0000184b do_action+978 system/core/debuggerd/crasher.cpp:228 00001459 thread_callback+24 system/core/debuggerd/crasher.cpp:90 00047317 __pthread_start(void*)+22 bionic/libc/bionic/pthread_create.cpp:202 (discriminator 1) 0001a7e5 __start_thread+34 bionic/libc/bionic/clone.cpp:46 (discriminator 1).
stack
öğesini bir mezar taşının tamamı için kullanabilirsiniz. Örnek:
stack < FS/data/tombstones/tombstone_05
Bu, geçerli dizinde bir hata raporunu yeni açtıysanız yararlı olur. Yerel kilitlenmeleri ve mezar taşlarını teşhis etme hakkında daha fazla bilgi için bkz. Yerel Kilitlenmeleri Teşhis Etme.
Çalışan bir işlemden yığın izleme (stack trace) veya mezar taşı alma
Çalışan bir işlemden yığın dökümü almak için debuggerd
aracını kullanabilirsiniz.
Döküm işlemi için komut satırından işlem kimliği (PID) kullanarak debuggerd
komutunu çağırın
tamamen stdout
adlı binaya geldi. İleti dizisindeki her ileti dizisinde yalnızca
-b
veya --backtrace
işaretini ekleyin.
Karmaşık bir gevşemeyi anlama
Bir uygulama kilitlendiğinde, yığın yapısı oldukça karmaşık olur. Aşağıdaki ayrıntılı örnekte, birçok karmaşıklık vurgulanmaktadır:
#00 pc 00000000007e6918 /system/priv-app/Velvet/Velvet.apk (offset 0x346b000) #01 pc 00000000001845cc /system/priv-app/Velvet/Velvet.apk (offset 0x346b000) #02 pc 00000000001847e4 /system/priv-app/Velvet/Velvet.apk (offset 0x346b000) #03 pc 00000000001805c0 /system/priv-app/Velvet/Velvet.apk (offset 0x346b000) (Java_com_google_speech_recognizer_AbstractRecognizer_nativeRun+176)
00–#03 numaralı kareler, diski kaydetmek için APK'da sıkıştırılmamış halde depolanan yerel JNI kodundandır
yerine bir .so
dosyasına ayıklayın. Yığının gevşetilmesi
Android 9 ve sonraki sürümlerde bu yaygın sorunla başa çıkmak için ayıklanan .so
dosyasına gerek yoktur
Android'e özel kılıf.
Geliştirici tarafından çıkarıldığı için #00–#02 numaralı çerçevelerin simge adları yoktur.
03. kare, sembollerin bulunduğu yerlerde sarıcının bunları kullandığını gösteriyor.
#04 pc 0000000000117550 /data/dalvik-cache/arm64/system@priv-app@Velvet@Velvet.apk@classes.dex (offset 0x108000) (com.google.speech.recognizer.AbstractRecognizer.nativeRun+160)
Çerçeve #04, önceden derlenmiş Java kodudur. Yaşlı gevşeyici bu noktada durmuş, ile yorgunluğunuzu atın.
#05 pc 0000000000559f88 /system/lib64/libart.so (art_quick_invoke_stub+584) #06 pc 00000000000ced40 /system/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+200) #07 pc 0000000000280cf0 /system/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+344) #08 pc 000000000027acac /system/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+948) #09 pc 000000000052abc0 /system/lib64/libart.so (MterpInvokeDirect+296) #10 pc 000000000054c614 /system/lib64/libart.so (ExecuteMterpImpl+14484)
05 ve 10 numaralı kareler, ART yorumcusu uygulamasından alınmıştır.
Android 9'dan önceki sürümlerdeki yığın açıcılar, bu kareleri bağlam olmadan gösterirdi
çevirmenin hangi kodu yorumladığını açıklayan 11. karedeki bir resimdir. Bu çerçeveler yalnızca
ART'ın kendisinde hata ayıklayorsunuz. Bir uygulamada hata ayıklıyorsanız bunları yoksayabilirsiniz. Örneğin,
simpleperf
, bu kareleri otomatik olarak atlar.
#11 pc 00000000001992d6 /system/priv-app/Velvet/Velvet.apk (offset 0x26cf000) (com.google.speech.recognizer.AbstractRecognizer.run+18)
11. çerçeve, yorumlanan Java kodudur.
#12 pc 00000000002547a8 /system/lib64/libart.so (_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_6JValueEb.llvm.780698333+496) #13 pc 000000000025a328 /system/lib64/libart.so (art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*)+216) #14 pc 000000000027ac90 /system/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+920) #15 pc 0000000000529880 /system/lib64/libart.so (MterpInvokeVirtual+584) #16 pc 000000000054c514 /system/lib64/libart.so (ExecuteMterpImpl+14228)
12-#16 numaralı çerçeveler, çevirmen uygulamasının kendisidir.
#17 pc 00000000002454a0 /system/priv-app/Velvet/Velvet.apk (offset 0x1322000) (com.google.android.apps.gsa.speech.e.c.c.call+28)
17. çerçeve, yorumlanan Java kodudur. Bu Java yöntemi 12 - 16 numaralı çevirmen çerçevelerine karşılık gelir.
#18 pc 00000000002547a8 /system/lib64/libart.so (_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_6JValueEb.llvm.780698333+496) #19 pc 0000000000519fd8 /system/lib64/libart.so (artQuickToInterpreterBridge+1032) #20 pc 00000000005630fc /system/lib64/libart.so (art_quick_to_interpreter_bridge+92)
18–#20 numaralı çerçeveler sanal makinenin kendisidir, derlenmiş Java kodundan yorumlanmış Java koduna geçiş kodudur.
#21 pc 00000000002ce44c /system/framework/arm64/boot.oat (offset 0xdc000) (java.util.concurrent.FutureTask.run+204)
21. çerçeve, #17 numaralı bölümde Java yöntemini çağıran derlenmiş Java yöntemidir.
#22 pc 0000000000559f88 /system/lib64/libart.so (art_quick_invoke_stub+584) #23 pc 00000000000ced40 /system/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+200) #24 pc 0000000000280cf0 /system/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+344) #25 pc 000000000027acac /system/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+948) #26 pc 0000000000529880 /system/lib64/libart.so (MterpInvokeVirtual+584) #27 pc 000000000054c514 /system/lib64/libart.so (ExecuteMterpImpl+14228)
22-#27 numaralı kareler, çevirmen uygulamasıdır ve yorumlanan metinden derlemek için kullanır.
#28 pc 00000000003ed69e /system/priv-app/Velvet/Velvet.apk (com.google.android.apps.gsa.shared.util.concurrent.b.e.run+22)
28 numaralı çerçeve, yorumlanan Java kodudur.
#29 pc 00000000002547a8 /system/lib64/libart.so (_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_6JValueEb.llvm.780698333+496) #30 pc 0000000000519fd8 /system/lib64/libart.so (artQuickToInterpreterBridge+1032) #31 pc 00000000005630fc /system/lib64/libart.so (art_quick_to_interpreter_bridge+92)
29–#31 numaralı kareler, derlenen kod ile yorumlanan kod arasındaki başka bir geçiştir.
#32 pc 0000000000329284 /system/framework/arm64/boot.oat (offset 0xdc000) (java.util.concurrent.ThreadPoolExecutor.runWorker+996) #33 pc 00000000003262a0 /system/framework/arm64/boot.oat (offset 0xdc000) (java.util.concurrent.ThreadPoolExecutor$Worker.run+64) #34 pc 00000000002037e8 /system/framework/arm64/boot.oat (offset 0xdc000) (java.lang.Thread.run+72)
32–#34 numaralı çerçeveler, birbirlerini doğrudan çağıran derlenmiş Java çerçeveleridir. Bu durumda, yerel çağrı yığın, Java çağrı yığınıyla aynıdır.
#35 pc 0000000000559f88 /system/lib64/libart.so (art_quick_invoke_stub+584) #36 pc 00000000000ced40 /system/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+200) #37 pc 0000000000280cf0 /system/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+344) #38 pc 000000000027acac /system/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+948) #39 pc 0000000000529f10 /system/lib64/libart.so (MterpInvokeSuper+1408) #40 pc 000000000054c594 /system/lib64/libart.so (ExecuteMterpImpl+14356)
35-#40 numaralı kareler çevirmenin kendisidir.
#41 pc 00000000003ed8e0 /system/priv-app/Velvet/Velvet.apk (com.google.android.apps.gsa.shared.util.concurrent.b.i.run+20)
41 numaralı çerçeve, yorumlanan Java kodudur.
#42 pc 00000000002547a8 /system/lib64/libart.so (_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_6JValueEb.llvm.780698333+496) #43 pc 0000000000519fd8 /system/lib64/libart.so (artQuickToInterpreterBridge+1032) #44 pc 00000000005630fc /system/lib64/libart.so (art_quick_to_interpreter_bridge+92) #45 pc 0000000000559f88 /system/lib64/libart.so (art_quick_invoke_stub+584) #46 pc 00000000000ced40 /system/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+200) #47 pc 0000000000460d18 /system/lib64/libart.so (art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*)+104) #48 pc 0000000000461de0 /system/lib64/libart.so (art::InvokeVirtualOrInterfaceWithJValues(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, jvalue*)+424) #49 pc 000000000048ccb0 /system/lib64/libart.so (art::Thread::CreateCallback(void*)+1120)
42–#49 numaralı kareler sanal makinenin kendisidir. Bu kez, yeni bir iş parçacığında Java'yı çalıştırmaya başlayan koddur.
#50 pc 0000000000082e24 /system/lib64/libc.so (__pthread_start(void*)+36) #51 pc 00000000000233bc /system/lib64/libc.so (__start_thread+68)
Tüm ileti dizilerinin başlaması gereken kareler #50–#51 arasındadır. Bu, libc
yeni iş parçacığı başlangıç kodu.