Native crash后的代码处理流程[dropbox相关]

时间:2021-05-20 08:23:01

ActivityManagerService能监测到native crash事件的发生:

1. 生成的tombstones文件是怎样保存到 dropbox的

root@gemini:/ # cd /data/tombstones
root@gemini:/data/tombstones # ls -al
-rw------- system   system     183907 2016-12-28 15:43 tombstone_00


root@gemini:/data/system/dropbox # ls -al
-rw------- system   system      18151 2016-12-28 15:43 SYSTEM_TOMBSTONE@1482911022835.txt.gz




{
        // Start watching for new tombstone files; will record them as they occur.
        // This gets registered with the singleton file observer thread.
        sTombstoneObserver = new FileObserver(TOMBSTONE_DIR.getPath(), FileObserver.CLOSE_WRITE) {
            @Override
            public void onEvent(int event, String path) {
                try {
                    File file = new File(TOMBSTONE_DIR, path);
                    if (file.isFile()) {
                        addFileToDropBox(db, prefs, headers, file.getPath(), LOG_SIZE, "SYSTEM_TOMBSTONE");
                    }
                } catch (IOException e) {
                    Slog.e(TAG, "Can't log tombstone", e);
                }
            }
        };


        sTombstoneObserver.startWatching();
}


2. ActivityManagerService监听tombstone 事件:
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
    public void startObservingNativeCrashes() {
        final NativeCrashListener ncl = new NativeCrashListener(this);
        ncl.start();
    }




构造函数:NativeCrashListener
    /*
     * Daemon thread that accept()s incoming domain socket connections from debuggerd
     * and processes the crash dump that is passed through.
     */
    NativeCrashListener(ActivityManagerService am) {
        mAm = am;
    }




这里没有找到start 函数:看下基类:thread
想起来了: thread总有调用 start, 且run()总有被重写:
final class NativeCrashListener extends Thread {
}
    /**
     * Starts the new Thread of execution. The <code>run()</code> method of
     * the receiver will be called by the receiver Thread itself (and not the
     * Thread calling <code>start()</code>).
     *
     * @throws IllegalThreadStateException - if this thread has already started.
     * @see Thread#run
     */
    public synchronized void start() {
        checkNotStarted();




        hasBeenStarted = true;




        nativeCreate(this, stackSize, daemon);
    }




    @Override
    public void run() {
            while (true) {
                InetSocketAddress peer = new InetSocketAddress();
                FileDescriptor peerFd = null;
                try {
                        consumeNativeCrashData(peerFd);
                    }
                }
    }




    // Read the crash report from the debuggerd connection
    void consumeNativeCrashData(FileDescriptor fd) {
        final byte[] buf = new byte[4096];
        final ByteArrayOutputStream os = new ByteArrayOutputStream(4096);




            // first, the pid and signal number
            int headerBytes = readExactly(fd, buf, 0, 8);




            int pid = unpackInt(buf, 0);
            int signal = unpackInt(buf, 4);
            if (DEBUG) {
                Slog.v(TAG, "Read pid=" + pid + " signal=" + signal);
            }




                    do {
                        // get some data
                        bytes = Os.read(fd, buf, 0, buf.length);
                        if (bytes > 0) {
                            // did we just get the EOD null byte?
                            if (buf[bytes-1] == 0) {
                                os.write(buf, 0, bytes-1);  // exclude the EOD token
                                break;
                            }
                            // no EOD, so collect it and read more
                            os.write(buf, 0, bytes);
                        }
                    } while (bytes > 0);




                    final String reportString = new String(os.toByteArray(), "UTF-8");
                    (new NativeCrashReporter(pr, signal, reportString)).start();
}




(new NativeCrashReporter(pr, signal, reportString)).start();
调用构造函数NativeCrashReporter,并调用start:
        @Override
        public void run() {
            try {
                CrashInfo ci = new CrashInfo();
                ci.exceptionClassName = "Native crash";
                ci.exceptionMessage = Os.strsignal(mSignal);
                ci.throwFileName = "unknown";
                ci.throwClassName = "unknown";
                ci.throwMethodName = "unknown";
                ci.stackTrace = mCrashReport;




                if (DEBUG) Slog.v(TAG, "Calling handleApplicationCrash()");
                mAm.handleApplicationCrashInner("native_crash", mApp, mApp.processName, ci);
                if (DEBUG) Slog.v(TAG, "<-- handleApplicationCrash() returned");
            } catch (Exception e) {
                Slog.e(TAG, "Unable to report native crash", e);
            }
        }
    }




3. 保存的文件名为:data_app_native_crash@1482911022817.txt                                    <
Process: com.example.ritter.fcandanr
Flags: 0x3888be46
Package: com.example.ritter.fcandanr v1 (1.0)
Build: Xiaomi/gemini/gemini:6.0.1/MXB48T/1.1.1:user/test-keys


*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'Xiaomi/gemini/gemini:6.0.1/MXB48T/1.1.1:user/test-keys'
Revision: '0'
ABI: 'arm'
pid: 9299, tid: 9299, name: ritter.fcandanr  >>> com.example.ritter.fcandanr <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
    r0 f5416ea0  r1 ffacc96c  r2 00430000  r3 00000000
    r4 f0be1b40  r5 ffacca50  r6 00000003  r7 00000000
    r8 00000000  r9 f5436500  sl f0be1b40  fp ffacca1c
    ip f3dffd15  sp ffacc960  lr e11d30db  pc f3dffd16  cpsr 600e0030


backtrace:
    #00 pc 00000d16  /data/app/com.example.ritter.fcandanr-1/lib/arm/libritterJNILib.so (Java_com_example_ritter_fcandanr_NdkJniUtils_getCLanguageString+1)
    #01 pc 0043c0d9  /data/app/com.example.ritter.fcandanr-1/oat/arm/base.odex (offset 0x2f2000) (java.lang.String com.example.ritter.fcandanr.NdkJniUtils.getCLanguageString()+76)
    #02 pc 0054e743  /data/app/com.example.ritter.fcandanr-1/oat/arm/base.odex (offset 0x2f2000) (void com.example.ritter.fcandanr.MainActivity.onClickNativeCrash(android.view.View)+126)
    #03 pc 000e61b1  /system/lib/libart.so (art_quick_invoke_stub_internal+64)
    #04 pc 003eb7f3  /system/lib/libart.so (art_quick_invoke_stub+170)
    #05 pc 007fdacc  [stack]