使用https://github.com/jaredrummler/AndroidProcesses库遇到的崩溃问题的“探索”

来源:互联网 发布:mysql自带可视化界面 编辑:程序博客网 时间:2024/04/20 07:21
AndroidProcesses库是jared rummler大神的双一杰作http://jaredrummler.com/,该库简单来说是通过读取/proc/pid/目录下的文件,获取对应进程的信息,具体功能移动至 https://github.com/jaredrummler/AndroidProcesses
最近我们项目中使用该库,线上收集到相关的崩溃信息如下(精简过后的backtrace):
Caused by: java.lang.ArrayIndexOutOfBoundsException: length=1; index=1at Stat.getComm(Stat.java:198)at AndroidProcess.getProcessName(AndroidProcess.java:44)at AndroidProcess.<init>(AndroidProcess.java:65)at AndroidAppProcess.<init>(AndroidAppProcess.java:48)
经分析应该是某些异常的情况出现,导致/proc/pid/stat的文件内容格式错乱或没有内容,临时的解决方案如下(加强代码的异常逻辑处理):
@@ -195,7 +195,8 @@ public final class Stat extends ProcFile {  * executable is swapped out.  */ public String getComm() {-    return fields[1].replace("(", "").replace(")", "");+    return fields != null && fields.length > 1 && fields[1] != null ?+        fields[1].replace("(", "").replace(")", "") : null; }

同时在github上提了一个issues 

在分析代码的过程中,发现一个有趣的现象,似乎/proc/pid/stat获取不到进程名(android应用对应的是包名),

通过现象分析发现进程名最多是15个字符,立即怀疑stat的文件生成或更新时进程名应该是有裁段的逻辑处理,

经翻查linux内核代码找到相关的关健代码如下

static ssize_t comm_write(struct file *file, const char __user *buf,size_t count, loff_t *offset){struct inode *inode = file_inode(file);struct task_struct *p;char buffer[TASK_COMM_LEN]; // TASK_COMM_LEN = 16const size_t maxlen = sizeof(buffer) - 1;memset(buffer, 0, sizeof(buffer));if (copy_from_user(buffer, buf, count > maxlen ? maxlen : count))return -EFAULT;p = get_proc_task(inode);if (!p)return -ESRCH;if (same_thread_group(current, p))set_task_comm(p, buffer);elsecount = -EINVAL;put_task_struct(p);return count;}TASK_COMM_LEN的定义在include/linux/sched.h167:#define TASK_COMM_LEN16725:charcomm[TASK_COMM_LEN];注:TASK_COMM_LEN是16,占用一位为作字符串的结构符,故stat文件中的进程名只有15位了

在github了提了一个issues
阅读全文
1 0