android FD leak 定位文件泄漏

R 上google 加入了一个fd leak 检测功能,基本实现如下:

SystemServer.java 中在system_server 进程创建一个Native 检测进程

 spawnFdLeakCheckThread();

frameworks/base/services/core/jni/com_android_server_SystemServer.cpp

参见dlopen()  ,加载该动态库,则会执行注册信号处理函数  __attribute__((constructor)) static void
ctor()

dlopen函数详解_u013531497的专栏-CSDN博客_dlopen函数

检测到文件句柄超支,则产生

raise(BIONIC_SIGNAL_FDTRACK); 信号;

定义信号:

bionic/libc/platform/bionic/reserved_signals.h

#define BIONIC_SIGNAL_FDTRACK (__SIGRTMIN + 7)

注册信号处理函数:

bionic/libfdtrack/fdtrack.cpp

实现打印:

bionic/libfdtrack/fdtrack.cpp

1、当sockFD=open(..,...) 返回<0 且错误码为 “-24” ,则发生了文件句柄超过最大值泄漏。

诸如 ”open,fopen,dlopen,pipe” 等系统调用出现fail,也就是返回值小于0的时候,可以怀疑是句柄泄露,但是我们还需要证实一下。

cat  /proc/pid/limits  可以查看进程资源限制

查看确定fd数量  /proc/pid/fd 

2、发下native 出现crash 但是没有打印对应的堆栈

通常情况exit(0) _exit(1)才不会打印堆栈,但是一般这样退出会打印一些提示信息

 pipe_set_size(...){
if (nr_pages > pipe->buffers &&
1129			(too_many_pipe_buffers_hard(user_bufs) ||
1130			 too_many_pipe_buffers_soft(user_bufs)) &&
1131			is_unprivileged_user()) {  ... }

}

内核会设置Pipe管道的大小,在这里出现了权限错误。权限异常需要满足如下3个条件:

   1. 当前设置的Pipe管道大小超过了上一次设置过的或者默认的管道大小。

    2. 当前用户组的所有Pipe管道的buffer总大小超过了软限制16*1024*4K或者硬限制(默认为0)。

    3. “ 忽略资源限制 ”以及 “系统管理任务” 这2类权限都不具备(默认值)。

这里是根据用户组来分配pipe_buffer 的,某个进程泄漏pipe ,则会影响整个用户组。

这里可以使用FDTrack 功能,在main中创建thread,执行同com_android_server_SystemServer.cpp 中,fdtrack 在收到信号会打印fd 句柄及对应的堆栈。

进入 “/proc/pid/fd” 目录,执行 “ls -l | grep pipe  > /data/leak_before.txt” 保存泄露前句柄信息;

目标进程创建一个线程,该线程间隔每5s运行一次,获取当前进程最大句柄数,当进程持有的最大句柄数超过阈值,打开 “libfdtrack.so” ;

复现句柄泄露问题

进程发送信号,”libfdtrack.so” 会将记录的FD堆栈信息打印出来。

 “/proc/pid/fd” 目录,执行 “ls -l | grep pipe  > /data/leak_after.txt” 保存泄露后句柄信息;

比较泄露前后句柄信息,找到泄露的句柄号,配合logcat打印出的FD堆栈信息即可顺利找到泄露点。

FdSanitizer 简介_cczhengv-CSDN博客

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值