接上文
上文提到通过jni调用android_os_Debug_dumpJavaBacktraceToFileTimeout
文件位置在:frameworks/base/core/jni/android_os_Debug.cpp
3.1
android_os_Debug_dumpJavaBacktraceToFileTimeout(),中又调用了dumpTraces()
参数 pid = pid,fileName = "/data/anr/anr_Date",timeoutSecs = 20
static jboolean android_os_Debug_dumpJavaBacktraceToFileTimeout(JNIEnv* env, jobject clazz,
jint pid, jstring fileName, jint timeoutSecs) {
const bool ret = dumpTraces(env, pid, fileName, timeoutSecs, kDebuggerdJavaBacktrace);
return ret ? JNI_TRUE : JNI_FALSE;
}
3.2
dumpTraces(),通过c++的open方法,将fd的值设为了"/data/anr/anr_Date"的文件描述符,然后调用dump_backtrace_to_file_timeout()方法
参数:pid = pid,fileName = "/data/anr/anr_Date",timeoutSecs = 20,dumpType = ”kDebuggerdJavaBacktrace“
static bool dumpTraces(JNIEnv* env, jint pid, jstring fileName, jint timeoutSecs, DebuggerdDumpType dumpType) {
android::base::unique_fd fd(open(fileNameChars.c_str(),
O_CREAT | O_WRONLY | O_NOFOLLOW | O_CLOEXEC | O_APPEND,
0666));
int res = dump_backtrace_to_file_timeout(pid, dumpType, timeoutSecs, fd);
return res == 0;
}
3.3
dump_backtrace_to_file_timeout(),调用了debuggerd_trigger_dump()
参数:pid_t tid = pid,dumpType = ”kDebuggerdJavaBacktrace“,fd = "/data/anr/anr_Date"的文件描述符
int dump_backtrace_to_file_timeout(pid_t tid, DebuggerdDumpType dump_type, int timeout_secs,int fd) {
android::base::unique_fd copy(dup(fd));
int timeout_ms = timeout_secs > 0 ? timeout_secs * 1000 : 0;
return debuggerd_trigger_dump(tid, dump_type, timeout_ms, std::move(copy)) ? 0 : -1;
}
3.4
debuggerd_trigger_dump(),这个方法会通过socket和别的进程进行通信,获取数据,是一个很重要的方法
1,首先通过GetProcessInfo()获取ProcessInfo,包括pid
2,通过socket_local_client_connect(),连接socket name = “kTombstonedInterceptSocketName” 的socket服务端
3,初始化pipe管道
4,给socket服务端发送数据
socket name = “kTombstonedInterceptSocketName” 的socket服务端,在[system](http://axr.htc.com/source/xref/Q_Mainline/system/)/[core](http://axr.htc.com/source/xref/Q_Mainline/system/core/)/[debuggerd](http://axr.htc.com/source/xref/Q_Mainline/system/core/debuggerd/)/[tombstoned](http://axr.htc.com/source/xref/Q_Mainline/system/core/debuggerd/tombstoned/)/[tombstoned.cpp](http://axr.htc.com/source/xref/Q_Mainline/system/core/debuggerd/tombstoned/tombstoned.cpp)的main方法中初始化
参数:pid_t tid = pid,dumpType = "kDebuggerdJavaBacktrace“,output_fd = "/data/anr/anr_Date"的文件描述符
bool debuggerd_trigger_dump(pid_t tid, DebuggerdDumpType dump_type, unsigned int timeout_ms,unique_fd output_fd) {
pid_t pid = tid;
if (dump_type == kDebuggerdJavaBacktrace) {
// Java dumps always get sent to the tgid, so we need to resolve our tid to a tgid.
android::procinfo::ProcessInfo procinfo;
std::string error;
//GetProcessInfo获取pid对应的procinfo
if (!android::procinfo::GetProcessInfo(tid, &procinfo, &error)) {
LOG(ERROR) << "libdebugged_client: failed to get process info: " << error;
return false;
}
pid = procinfo.pid;
}
//通过socket_local_client_connect,连接socket name = kTombstonedInterceptSocketName 的socket服务端
if (socket_local_client_connect(set_timeout(sockfd.get()), kTombstonedInterceptSocketName,
ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET) == -1) {
PLOG(ERROR) << "libdebuggerd_client: failed to connect to tombstoned";
return false;
}
//初始化request
InterceptRequest req = {.pid = pid, .dump_type = dump_type}
// Create an intermediate pipe to pass to the other end.
unique_fd pipe_read, pipe_write;
//调用Pipe创建linux中的一种数据传输方式--管道,pipe_read为读出管道中的数据的fd,pipe_write为写入管道的数据的fd
if (!Pipe(&pipe_read, &pipe_write)) {
PLOG(ERROR) << "libdebuggerd_client: failed to create pipe";
return false;
}
//调用SendFileDescriptors()方法,,给sockfd代表的socket服务端发送数据
//sockfd代表的服务端为socket name = kTombstonedInterceptSocketName 的socket服务端
//req = {.pid = pid, .dump_type = dump_type = "kDebuggerdJavaBacktrace" }
ssize_t rc = SendFileDescriptors(set_timeout(sockfd), &req, sizeof(req), pipe_write.get());
}
待续。。。