Bagian ini merangkum fitur yang berguna dan perintah terkait untuk men-debug, melacak, dan membuat profil kode platform Android asli saat mengembangkan fitur tingkat platform.
Catatan: Halaman di bagian ini dan di tempat lain dalam situs ini merekomendasikan penggunaan adb
sehubungan dengan argumen setprop
untuk men-debug aspek tertentu Android. Di Android 7.x dan yang lebih rendah, nama properti memiliki batas panjang 32 karakter. Ini berarti bahwa untuk membuat properti bungkus dengan nama aplikasi, perlu memotong nama agar pas. Di Android 8.0 dan yang lebih tinggi, batas ini jauh lebih besar dan seharusnya tidak memerlukan pemotongan.
Halaman ini membahas dasar-dasar seputar dump error yang ditemukan dalam keluaran logcat. Halaman lain memiliki lebih banyak detail tentang mendiagnosis kerusakan asli , menjelajahi layanan sistem dengan dumpsys
, melihat memori asli , jaringan , dan penggunaan RAM , menggunakan AddressSanitizer untuk mendeteksi bug memori dalam kode asli, mengevaluasi masalah kinerja (termasuk systrace ), dan menggunakan debugger .
Tempat pembuangan sampah dan batu nisan
Saat eksekusi yang ditautkan secara dinamis dimulai, beberapa penangan sinyal terdaftar yang, jika terjadi error, menyebabkan crash dump dasar ditulis ke logcat dan file batu nisan yang lebih detail akan ditulis ke /data/tombstones/
. Batu nisan adalah file dengan data tambahan tentang proses macet. Secara khusus, ini berisi jejak tumpukan untuk semua utas dalam proses mogok (bukan hanya utas yang menangkap sinyal), peta memori penuh, dan daftar semua deskriptor file yang terbuka.
Sebelum Android 8.0, crash ditangani oleh debuggerd
dan debuggerd64
daemon. Di Android 8.0 dan yang lebih tinggi, crash_dump32
dan crash_dump64
muncul sesuai kebutuhan.
Ada kemungkinan untuk dumper kemacetan untuk melampirkan hanya jika tidak ada yang lain yang telah terpasang, yang berarti bahwa menggunakan alat seperti strace
atau lldb
mencegah terjadinya crash dump.
Contoh keluaran (dengan cap waktu dan informasi asing dihapus):
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 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
Baris keluaran terakhir memberikan lokasi penuh batu nisan pada disk.
Jika Anda memiliki binari yang tidak dibatasi, Anda bisa mendapatkan pelepasan yang lebih mendetail dengan informasi nomor baris dengan menempelkan tumpukan ke dalam development/scripts/stack
:
development/scripts/stack
Tip: Untuk kenyamanan, jika Anda sudah menjalankan lunch
, maka stack
sudah ada di $PATH
Anda sehingga Anda tidak perlu menyediakan path lengkap.
Contoh keluaran (berdasarkan keluaran logcat di atas):
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)
Anda dapat menggunakan stack
di seluruh batu nisan. Contoh:
stack < FS/data/tombstones/tombstone_05
Ini berguna jika Anda baru saja membuka ritsleting laporan bug di direktori saat ini. Untuk informasi lebih lanjut tentang mendiagnosis kerusakan bawaan dan batu nisan, lihat Mendiagnosis Mogok Asli .
Mendapatkan jejak tumpukan / batu nisan dari proses yang sedang berjalan
Anda dapat menggunakan alat debuggerd
untuk mendapatkan tumpukan dump dari proses yang sedang berjalan. Dari baris perintah, aktifkan debuggerd
menggunakan ID proses (PID) untuk membuang batu nisan lengkap ke stdout
. Untuk mendapatkan tumpukan untuk setiap utas dalam proses, sertakan tanda -b
atau --backtrace
.
Memahami relaksasi yang kompleks
Saat aplikasi mogok, tumpukan cenderung menjadi cukup rumit. Contoh detail berikut menyoroti banyak kerumitan:
#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)
Frame # 00– # 03 berasal dari kode JNI asli yang disimpan tanpa kompresi di APK untuk menghemat ruang disk daripada diekstraksi menjadi file .so
terpisah. Stack unwinder di Android 9 dan yang lebih tinggi tidak memerlukan file .so
diekstrak untuk menangani kasus umum khusus Android ini.
Bingkai # 00– # 02 tidak memiliki nama simbol karena dicopot oleh pengembang.
Frame # 03 menunjukkan bahwa di mana simbol tersedia, unwinder menggunakannya.
#04 pc 0000000000117550 /data/dalvik-cache/arm64/system@priv-app@Velvet@Velvet.apk@classes.dex (offset 0x108000) (com.google.speech.recognizer.AbstractRecognizer.nativeRun+160)
Frame # 04 adalah kode Java yang dikompilasi sebelumnya. Pelepas lelah yang lama akan berhenti di sini, tidak dapat melepas lelah melalui Jawa.
#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)
Bingkai # 05– # 10 berasal dari penerapan juru ART. Stack unwinder dalam rilis yang lebih rendah dari Android 9 akan menampilkan frame ini tanpa konteks frame # 11 yang menjelaskan kode apa yang diinterpretasikan oleh interpreter. Bingkai ini berguna jika Anda men-debug ART itu sendiri. Jika Anda men-debug aplikasi, Anda dapat mengabaikannya. Beberapa alat, seperti simpleperf
, secara otomatis menghilangkan bingkai ini.
#11 pc 00000000001992d6 /system/priv-app/Velvet/Velvet.apk (offset 0x26cf000) (com.google.speech.recognizer.AbstractRecognizer.run+18)
Frame # 11 adalah kode Java yang diinterpretasikan.
#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)
Frame # 12– # 16 adalah implementasi interpreter itu sendiri.
#17 pc 00000000002454a0 /system/priv-app/Velvet/Velvet.apk (offset 0x1322000) (com.google.android.apps.gsa.speech.e.c.c.call+28)
Frame # 17 adalah kode Java yang diinterpretasikan. Metode Java ini sesuai dengan kerangka interpreter # 12– # 16.
#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)
Frame # 18– # 20 adalah VM itu sendiri, kode untuk transisi dari kode Java yang dikompilasi ke kode Java yang diinterpretasikan.
#21 pc 00000000002ce44c /system/framework/arm64/boot.oat (offset 0xdc000) (java.util.concurrent.FutureTask.run+204)
Frame # 21 adalah metode Java terkompilasi yang memanggil metode Java di # 17.
#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)
Frames # 22– # 27 adalah implementasi interpreter, membuat pemanggilan metode dari kode yang diinterpretasikan ke metode yang dikompilasi.
#28 pc 00000000003ed69e /system/priv-app/Velvet/Velvet.apk (com.google.android.apps.gsa.shared.util.concurrent.b.e.run+22)
Frame # 28 adalah kode Java yang sedang diinterpretasikan.
#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)
Frame # 29– # 31 adalah transisi lain antara kode yang dikompilasi dan kode yang diinterpretasikan.
#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)
Bingkai # 32– # 34 adalah bingkai Java yang dikompilasi yang memanggil satu sama lain secara langsung. Dalam hal ini stack panggilan native sama dengan stack panggilan Java.
#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)
Bingkai # 35– # 40 adalah penafsir itu sendiri.
#41 pc 00000000003ed8e0 /system/priv-app/Velvet/Velvet.apk (com.google.android.apps.gsa.shared.util.concurrent.b.i.run+20)
Frame # 41 adalah kode Java yang diinterpretasikan.
#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)
Bingkai # 42– # 49 adalah VM itu sendiri. Kali ini kode yang mulai menjalankan Java di utas baru.
#50 pc 0000000000082e24 /system/lib64/libc.so (__pthread_start(void*)+36) #51 pc 00000000000233bc /system/lib64/libc.so (__start_thread+68)
Bingkai # 50– # 51 adalah bagaimana semua utas harus dimulai. Ini adalah kode awal utas baru libc
.