Saya memindahkan proyek ke Android Native Development Kit baru (yaitu JNI) dan saya ingin menangkap SIGSEGV, seandainya itu terjadi (mungkin juga SIGILL, SIGABRT, SIGFPE) untuk menampilkan dialog pelaporan kerusakan yang bagus, alih-alih (atau sebelum) apa yang saat ini terjadi: proses mati tanpa basa-basi dan mungkin beberapa upaya oleh OS untuk memulai ulang. ( Sunting: VM JVM / Dalvik menangkap sinyal dan mencatat jejak tumpukan dan informasi berguna lainnya; Saya hanya ingin menawarkan kepada pengguna opsi untuk mengirimkan info itu kepada saya.)
Situasinya adalah: banyak kode C yang tidak saya tulis melakukan sebagian besar pekerjaan dalam aplikasi ini (semua logika permainan) dan meskipun telah diuji dengan baik di banyak platform lain, sangat mungkin bahwa saya, di Android saya port, akan memberinya sampah dan menyebabkan crash pada kode native, jadi saya ingin crash dump (baik native maupun Java) yang saat ini muncul di log Android (saya kira ini akan menjadi stderr dalam situasi non-Android). Saya bebas memodifikasi kode C dan Java secara sewenang-wenang, meskipun panggilan balik (keduanya masuk dan keluar dari JNI) berjumlah sekitar 40 dan jelas, poin bonus untuk perbedaan kecil.
Saya pernah mendengar tentang pustaka rantai sinyal di J2SE, libjsig.so, dan jika saya dapat dengan aman memasang penangan sinyal seperti itu di Android, itu akan menyelesaikan bagian yang menarik dari pertanyaan saya, tetapi saya tidak melihat pustaka semacam itu untuk Android / Dalvik .
Jawaban:
Sunting: Dari Jelly Bean dan seterusnya Anda tidak bisa mendapatkan jejak tumpukan, karena
READ_LOGS
pergi . :-(Saya benar-benar mendapat penangan sinyal yang bekerja tanpa melakukan sesuatu yang terlalu eksotis, dan telah merilis kode yang menggunakannya, yang dapat Anda lihat di github (edit: menautkan ke rilis historis; Saya menghapus penangan kerusakan sejak itu). Begini caranya:
sigaction()
untuk menangkap sinyal dan menyimpan penangan lama. ( android.c: 570 )startActivity()
aktivitas yang ditandai sebagai perlu berada dalam prosesnya sendiri. ( SGTPuzzles.java:962 , AndroidManifest.xml: 28 )debuggerd
untuk mencatat jejak asli yang bagus untuk Anda, dan kemudian prosesnya akan mati. ( debugger.c , debuggerd.c )logcat -d -v threadtime
dan luncurkanACTION_SEND
dengan penerima, subjek, dan isi yang terisi. Pengguna harus menekan Kirim. ( CrashHandler.java , SGTPuzzles.java:462 , strings.xml: 41logcat
gagal atau membutuhkan waktu lebih dari beberapa detik. Saya telah menemukan satu perangkat, T-Mobile Pulse / Huawei U8220, di mana logcat segera masuk ke statusT
(dilacak) dan hang. ( CrashHandler.java:70 , strings.xml: 51 )Dalam situasi non-Android, beberapa di antaranya akan berbeda. Anda perlu mengumpulkan jejak asli Anda sendiri, lihat pertanyaan lain ini , bergantung pada jenis libc yang Anda miliki. Anda perlu menangani pembuangan jejak itu, meluncurkan proses penanganan kerusakan yang terpisah, dan mengirim email dengan beberapa cara yang sesuai untuk platform Anda, tetapi saya membayangkan pendekatan umum harus tetap berfungsi.
sumber
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
debuggerd
keluaran apa pun ?Saya sedikit terlambat, tapi aku punya kebutuhan yang sama persis, dan saya telah mengembangkan sebuah perpustakaan kecil untuk mengatasi itu, dengan menangkap crash umum (
SEGV
,SIBGUS
, dll) di dalam kode JNI , dan menggantinya dengan biasajava.lang.Error
pengecualian . Bonus, jika klien berjalan pada Android> =4.1.1
, jejak stack embeds diselesaikan backtrace kecelakaan (pseudo-jejak yang berisi penuh jejak stack asli). Anda tidak akan pulih dari kerusakan parah (mis. Jika Anda merusak pengalokasi, misalnya), tetapi setidaknya itu memungkinkan Anda untuk memulihkan dari sebagian besar crash . (harap laporkan keberhasilan dan kegagalan, kodenya masih baru)Info lebih lanjut di https://github.com/xroche/coffeecatch (kode adalah lisensi BSD 2-Clauses )
sumber
FWIW, Google Breakpad berfungsi dengan baik di Android. Saya melakukan pekerjaan porting, dan kami mengirimkannya sebagai bagian dari Firefox Mobile. Ini memerlukan sedikit penyiapan, karena ini tidak memberi Anda pelacakan tumpukan di sisi klien, tetapi mengirimi Anda memori tumpukan mentah dan melakukan tumpukan berjalan di sisi server (jadi Anda tidak perlu mengirimkan simbol debug dengan aplikasi Anda ).
sumber
Dalam pengalaman saya yang terbatas (non-Android), SIGSEGV dalam kode JNI biasanya akan merusak JVM sebelum kontrol dikembalikan ke kode Java Anda. Saya samar-samar ingat pernah mendengar tentang beberapa JVM non-Sun yang memungkinkan Anda menangkap SIGSEGV, tetapi AFAICR Anda tidak dapat berharap dapat melakukannya.
Anda dapat mencoba menangkapnya di C (lihat sigaction (2)), meskipun Anda dapat melakukan sangat sedikit setelah penangan SIGSEGV (atau SIGFPE atau SIGILL) karena perilaku berkelanjutan dari suatu proses secara resmi tidak ditentukan.
sumber
_Unwind_Backtrace
dariunwind.h
akan dibutuhkan sebagai gantinya.