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

AndroidProcesses库是jared rummler大神的双一杰作http://jaredrummler.com/,该库简单来说是通过读取/proc/pid/目录下的文件,获取对应进程的信息,具体功能移动至 https://github.com/jaredrummler/AndroidProcesses最近我们项目中使用该库,线上收集到相关的崩溃信息如下(精简过后的backtrace):
Caused by: java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
	at 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 = 16
	const 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);
	else
		count = -EINVAL;


	put_task_struct(p);


	return count;
}



TASK_COMM_LEN的定义在include/linux/sched.h
167:#define TASK_COMM_LEN			16
725:	char				comm[TASK_COMM_LEN];


注:TASK_COMM_LEN是16,占用一位为作字符串的结构符,故stat文件中的进程名只有15位了

在github了提了一个 issues
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值