Board logo

标题: 侦测程序句柄泄露的统计方法(2) [打印本页]

作者: look_w    时间: 2018-6-13 14:48     标题: 侦测程序句柄泄露的统计方法(2)

句柄泄露句柄泄露造成句柄泄露的主要原因,是进程在调用系统文件之后,没有释放已经打开的文件句柄。在 Linux 系统中,进程与文件之间是通过“打开文件”操作建立连接,文件系统会返回文件句柄来唯一标识进程与文件的连接。每当一个进程执行完毕之后,Linux 系统会将与进程相关的文件句柄自动释放。但是,如果进程一直处于执行状态,文件的句柄只能通过“关闭文件”操作来自我释放。与 Windows 系统的设置不同,Linux 系统对进程可以调用的文件句柄数做了限制,在默认情况下,每个进程可以调用的最大句柄数为 1024 个。超过了这个数值,进程则无法获得新的句柄。因此,句柄的泄露将会对进程的功能失效造成极大的隐患。
如何修改系统最大句柄数Linux 中,单个进程能够打开的最大文件句柄数量是可以配置的,系统默认是 1024。当单个进程打开的文件句柄数量超过了系统定义的值,就会出现“Too many files open”的错误提示。用户可以通过以下命令查看系统定义的最大值:
1
ulimit – n




对于一般的应用程序而言 1024 已经完全够用了,但是有些进程处理大量请求,很有可能 1024 就不够用了,则需要调整系统参数,来适应应用的变化。Linux 有硬性和软性设置两种,都可以通过 ulimit 来设置。例如
1
ulimit – HSn 2048




以上命令就可以设置 H(硬性),S(软性)的值为 2048。设定完成后,一旦系统重启,就又恢复成默认值了。
句柄泄露的实例以下是一个能够造成文件句柄泄露的实例。
1
2
3
4
5
6
7
8
9
# define Maximum 1024
Int i = 0;
while(i< Maximum)
{
fh = open("/home/ychengc/filehandle.c",O_CREAT |
O_WRONLY ,S_IRUSR|S_IWU        SR);
printf("%d\n",fh);
i++;
}




在这段程序中,进程连续 1024 次向系统申请文件 /home/ychengc/filehandle.c的句柄。理论上,每次都应该成功。但是,我们却发现 fh 的最小值是 3,最大值是 1023。当 fh 超过 1023 后,每次申请的句柄 ID 都是等于-1。造成这种情况的原因,是每个进程都会默认的保留 3 个文件描述符,文件描述符 0、1、2 分别代表标准输入、标准输出和标准错误输出。因此,这个进程一共向系统申请了 1027 个文件描述符,超过了系统最大值 1024 的限制,导致最后三次的申请都是失败的。
Linux 检测句柄的方法   在 Linux 平台上,lsof(list open files)是一个列出当前系统打开文件的工具。在 Linux 环境下,任何事物都以文件的形式存在,系统在后台为应用程序分配了一个文件描述符,无论这个文件的本质如何,该文件描述符为应用程序与基础操作系统之间的交互提供了通用接口。因为应用程序打开文件的描述符列表提供了大量关于这个应用程序本身的信息,因此通过 lsof 工具能够查看这个列表对系统监测以及排错将是很有帮助的。
在终端下输入 lsof 即可显示系统打开的文件,因为 lsof 需要访问核心内存和各种文件,所以必须以 root 用户的身份运行它才能够充分地发挥其功能。屏幕显示如下:
1
2
3
4
5
COMMAND     PID    USER   FD      TYPE     DEVICE      SIZE       NODE NAME
init          1    root  cwd       DIR        3,2      4096          2 /
init          1    root  rtd       DIR        3,2      4096          2 /
init          1    root  txt       REG        3,2     32684    1200637 /sbin/init
……




lsof 输出各列信息的意义如下:
COMMAND:进程的名称
PID:进程标识符
USER:进程所有者
FD:文件描述符,应用程序通过文件描述符识别该文件。如 cwd、txt 等
TYPE:文件类型,如 DIR、REG 等
DEVICE:指定磁盘的名称
SIZE:文件的大小
NODE:索引节点(文件在磁盘上的标识)
NAME:打开文件的确切名称
在 Linux 系统中可以用 man lsof 查看详细的介绍和参数使用方法,在这里不作过多介绍。在侦测程序句柄泄露的应用中,我们主要用到 lsof 的如下使用方法:
1
lsof – p PID




PID 是指我们要侦测程序的进程号,可以用命令 ps – ef 来得到。我们以进程号 14946 为例:
1
2
3
4
5
6
7
8
9
10
11
# lsof -p 14946
COMMAND     PID USER   FD   TYPE  DEVICE     SIZE   NODE NAME
rpc.rquot 14946 root  cwd    DIR     3,2     4096      2 /
rpc.rquot 14946 root  rtd    DIR     3,2     4096      2 /
rpc.rquot 14946 root txt REG 3,2 65292 267543
/usr/sbin/rpc.rquotad
rpc.rquot 14946 root mem REG 3,2 45889 535442
/lib/libnss_files-2.3.4.so
rpc.rquot 14946 root mem REG 3,2 1454802 541622 /lib/tls/
libc-2.3.4.so
……




每一行就代表该进程正在使用的一个文件,即句柄。统计行数总和就是该进程打开的所有句柄数量,这为我们用统计方法侦测句柄泄露提供的依据。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0