安卓native崩溃处理

安卓native崩溃处理

当安卓调用native方法崩溃的时候,一般是不会直接给出代码错误的地方,而是报一个内存地址,而且光看locat是不能直接拿到地址,这时候就需要借助breakpad来获取崩溃日志 ,demo我已经上传到github

先加载一个breakpad的module 然后初始化

    private File externalReportPath;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(
                    this,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    WRITE_EXTERNAL_STORAGE_REQUEST_CODE);
        } else {
            initExternalReportPath();
        }

        findViewById(R.id.crash_btn)
                .setOnClickListener(
                        new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                initBreakPad();
                                crash();
                                // copy core dump to sdcard
                            }
                        });
    }

   private void initExternalReportPath() {
        externalReportPath = new File(Environment.getExternalStorageDirectory(), "crashDump");
        if (!externalReportPath.exists()) {
            externalReportPath.mkdirs();
        }
    }

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(
                    this,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    WRITE_EXTERNAL_STORAGE_REQUEST_CODE);
        } else {
            initExternalReportPath();
        }

private void initBreakPad() {
        if (externalReportPath == null) {
            externalReportPath = new File(getFilesDir(), "crashDump");
            if (!externalReportPath.exists()) {
                externalReportPath.mkdirs();
            }
        }
        BreakpadInit.initBreakpad(externalReportPath.getAbsolutePath());
    }

点击崩溃之后,到SD卡中的crashDump文件夹找崩溃文件是一个dmp结尾的文件

dbeec5f2-9fe4-4f0f-80ef4382-2f1108cd.dmp

然后我配置了个ubuntu ,下载breakpad的源码,因为breakpad的编译需要linux环境,或者mac环境。

需要翻墙下载

./configure && make之后  在breakpad/src/processor的目录下生成minidump_stackwalk文件,

然后就可以对dmp文件进行转化,minidump_stackwalk  /home/xwg/桌面/dbeec5f2-9fe4-4f0f-
80ef4382-2f1108cd.dmp  > /home/xwg/桌面/log.txt

log日志是这样的  ,2个关键信息

1.cpu是arm64的,我用的真机;

2.报错的代码地址是0x600

然后现在最新版本的NDK

选择windows的,下载完之后解压

然后到D:\下载\android-ndk-r16b-windows-x86_64\android-ndk-r16b\toolchains\aarch64-linux-android-4.9\prebuilt\windows-x86_64\bin    目录下 cmd命令    用aarch64-linux-android-addr2line来找so文件代码地址对应的代码行

aarch64-linux-android-addr2line -f -C -e D:\dowload_demo\Chapter01-master\sample\build\intermediates\transforms\mergeJniLibs\debug\0\lib\arm64-v8a\libcrash-lib.so 0x600

最后就能看到具体哪一行c代码报错了,有兴趣的朋友可以试试