Bạn đã thử thư viện coffeecatch?
Đây là bộ thu tín hiệu JNI cho phép chuyển tín hiệu SIGSEGV (+) thành ngoại lệ java với dấu chéo jni/java hỗn hợp. Nó hoạt động lên đến API-19, nhưng tôi không có cơ hội để kiểm tra nó trên API> 19. Nó cung cấp các địa chỉ chương trình có thể được chuyển tới addr2line để lấy các tham chiếu cuối cùng tới một nguồn.
Mã mẫu:
#include "coffeejni.h"
#include "coffeecatch.h"
void MyClass::foo(JNIEnv *env, int arg1, int arg2) {
....
int rc;
COFFEE_TRY_JNI(env, rc = crashInside(arg1, arg2));
....
}
Ví dụ về các dấu vết:
F/myapp (24535): "DESIGN ERROR": thread=t1
F/myapp (24535): java.lang.Error: signal 11 (Address not mapped to object) at address 0xdeadbaad [at libc.so:0x18282]
F/myapp (24535): at com.example.NativeSupport.nsc(Native Method)
F/myapp (24535): at com.example.NativeSupport.nsc_quiet(NativeSupport.java:328)
F/myapp (24535): at com.example.NativeSupport.loop(NativeSupport.java:287)
F/myapp (24535): at com.example.NativeSupport.access$2(NativeSupport.java:274)
F/myapp (24535): at com.example.NativeSupport$2.run(NativeSupport.java:124)
F/myapp (24535): at java.lang.Thread.run(Thread.java:856)
F/myapp (24535): Caused by: java.lang.Error: signal 11 (Address not mapped to object) at address 0xdeadbaad [at libc.so:0x18282]
F/myapp (24535): at system.lib.libc_so.0x18282(Native Method)
F/myapp (24535): at system.lib.libc_so.0xdc04(abort:0x4:0)
F/myapp (24535): at data.data.example.lib.libexample_so.0xf147(Native Method)
F/myapp (24535): at data.data.example.lib.libexample_so.0x12d1b(Native Method)
F/myapp (24535): at data.data.example.lib.libexample_so.0x1347b(Native Method)
F/myapp (24535): at data.data.example.lib.libexample_so.0x13969(Native Method)
F/myapp (24535): at data.data.example.lib.libexample_so.0x13ab3(Native Method)
F/myapp (24535): at data.data.example.lib.libexample_so.0x17a9b(Native Method)
F/myapp (24535): at system.lib.libdvm_so.0x1f4b0(dvmPlatformInvoke:0x70:0)
F/myapp (24535): at system.lib.libdvm_so.0x4dfa5(dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*):0x164:0)
F/myapp (24535): at system.lib.libdvm_so.0x28920(Native Method)
F/myapp (24535): at system.lib.libdvm_so.0x2d0b0(dvmInterpret(Thread*, Method const*, JValue*):0xb4:0)
F/myapp (24535): at system.lib.libdvm_so.0x5f599(dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list):0x110:0)
F/myapp (24535): at system.lib.libdvm_so.0x5f5c3(dvmCallMethod(Thread*, Method const*, Object*, JValue*, ...):0x14:0)
F/myapp (24535): at system.lib.libdvm_so.0x549eb(Native Method)
F/myapp (24535): at system.lib.libc_so.0x12dd0(__thread_entry:0x30:0)
F/myapp (24535): at system.lib.libc_so.0x12534(pthread_create:0xac:0)
Native (JNI) một phần của stack trace là:
F/myapp (24535): at data.data.example.lib.libexample_so.0xf147(Native Method)
F/myapp (24535): at data.data.example.lib.libexample_so.0x12d1b(Native Method)
F/myapp (24535): at data.data.example.lib.libexample_so.0x1347b(Native Method)
F/myapp (24535): at data.data.example.lib.libexample_so.0x13969(Native Method)
F/myapp (24535): at data.data.example.lib.libexample_so.0x13ab3(Native Method)
F/myapp (24535): at data.data.example.lib.libexample_so.0x17a9b(Native Method)
Và cuối cùng có được một humanoid- backtrace có thể đọc được:
cd android-ndk/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin
./arm-linux-androideabi-addr2line -e /home/joe/myproj/obj/local/armeabi-v7a/libexample.so 0xf147 0x12d1b 0x1347b 0x13969 0x13ab3 0x17a9b
Chỉ cần rõ ràng: bạn đang cố gắng viết trình xử lý sự cố trong ứng dụng để ghi lại dấu vết ngăn xếp sau khi lỗi? Trình xử lý tín hiệu không có ngăn xếp riêng của nó trừ khi 'sigaltstack' được sử dụng, mặc dù có thể ngăn xếp ngăn xếp không biết cách bước qua khung ngăn xếp tín hiệu. Mục tiêu cuối cùng của bạn là gì? ACRA cho NDK? – fadden
@fadden: đúng, tôi muốn nhận dấu vết ngăn xếp sau dấu vết. Nó sẽ xuất hiện như là trình xử lý tín hiệu có ngăn xếp riêng của nó, nó bắt nguồn từ 'art :: handleFault' hoặc một cái gì đó tương tự (trên 5.0). ACRA là gì? –
Tôi nghe một tin đồn rằng ART đã cung cấp bộ xử lý tín hiệu riêng của mình bị xích vào người xử lý trước đó; nếu đó là trường hợp, bạn sẽ thấy hành vi khác nhau trên 5.0 so với 4.x với Dalvik. Đây là trên đầu trang của trình xử lý tín hiệu được cài đặt hệ thống, cung cấp trình xử lý hệ thống debuggerd (kết quả này sẽ xuất ra dấu vết ngăn xếp tới tệp nhật ký sau khi xảy ra lỗi gốc). Tôi không nghĩ rằng lib pthread Android đang sử dụng 'sigaltstack', nhưng tôi đã không kiểm tra trong một thời gian. Bạn sẽ cần phải đào SP ra khỏi khung tín hiệu và sử dụng nó như là điểm thư giãn của bạn, thay vì SP hiện tại. – fadden