ActivityManagerService能监测到native crash事件的发生:
1. 生成的tombstones文件是怎样保存到 dropbox的
root@gemini:/ # cd /data/tombstonesroot@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]