问题源于eventfd/timerfd/signalfd等内核匿名fd被lsof默认忽略,需通过lsof -e/-D选项、/proc/PID/fdinfo/type字段、inotifywait监控、bpftrace追踪系统调用或/proc/PID/status中FDs与FDSize对比来定位。

当系统报错“too many open files”,但使用 lsof 查看进程打开文件数却显示极少,尤其未见大量 eventfd、timerfd 或 signalfd 等 fd 时,问题往往源于这些 fd 被内核隐藏——它们不被 lsof 默认识别或枚举。以下是定位与暴露这些隐藏 fd 的具体操作:
一、启用 lsof 的 -e 选项强制扫描所有 fd 类型
默认 lsof 会跳过部分匿名 fd(如 eventfd/timerfd),需显式启用扩展扫描模式以覆盖内核抽象 fd。
1、执行命令:lsof -p <PID> -e /proc/<PID>/fdinfo,其中 -e 参数指定排除路径,此处反向提示 lsof 需深入解析 fdinfo。
2、若失败,改用:lsof -p <PID> +D /proc/<PID>/fd,强制遍历 fd 目录符号链接并尝试解析目标类型。
3、检查输出中是否出现 anon_inode 字样,该字符串即为 eventfd/timerfd/signalfd 的统一标识。
二、直接读取 /proc/<PID>/fdinfo/ 下的 fd 元数据
/proc/<PID>/fdinfo/ 目录下每个数字文件对应一个 fd 的详细属性,其中 type 字段明确标示 fd 类型,可精准识别被隐藏的 fd。
1、列出目标进程所有 fd 编号:ls -l /proc/<PID>/fd/ | wc -l,确认实际 fd 数量远超 lsof 显示值。
2、逐个检查 fdinfo:grep -H "type:" /proc/<PID>/fdinfo/* 2>/dev/null | grep -E "(eventfd|timerfd|signalfd)"。
3、统计匹配行数:grep -H "type:" /proc/<PID>/fdinfo/* 2>/dev/null | grep -c -E "(eventfd|timerfd|signalfd)",所得数值即为隐藏 fd 总量。
三、使用 inotifywait 捕获 fd 创建行为
若隐藏 fd 动态高频创建,可在进程启动前注入监控,实时捕获 anon_inode fd 的生成事件。
1、在目标进程工作目录运行:inotifywait -m -e create,attrib /proc/<PID>/fdinfo/,持续监听 fdinfo 子文件变化。
2、触发业务逻辑使进程创建新 fd,观察 inotifywait 输出中新增的数字文件名。
3、立即对新文件执行:cat /proc/<PID>/fdinfo/<FD_NUM>,验证其 type 字段是否为 eventfd/timerfd/signalfd。
四、通过 eBPF 工具 bpftrace 实时追踪 syscalls
利用内核级追踪绕过用户态工具限制,直接捕获进程调用 eventfd2()、timerfd_create()、signalfd4() 等系统调用的行为。
1、安装 bpftrace 后执行:bpftrace -e 'tracepoint:syscalls:sys_enter_eventfd2 { printf("eventfd created by PID %d\n", pid); }'。
2、并行运行:bpftrace -e 'tracepoint:syscalls:sys_enter_timerfd_create { printf("timerfd created by PID %d\n", pid); }'。
3、合并输出结果,筛选出目标 PID 对应的创建记录,确认其调用频次与 ulimit -n 限制的关系。
五、检查 /proc/<PID>/status 中的 FDSize 与 FDs 字段
/proc/<PID>/status 文件提供内核维护的 fd 统计快照,其中 FDSize 表示当前分配的 fd 位图大小,FDs 表示已使用的 fd 数量,二者差异可反映隐藏 fd 占用情况。
1、执行:grep -E "FDSize|FDs" /proc/<PID>/status,获取原始数值。
2、若 FDs 值接近或等于 FDSize,且远高于 lsof 报告值,则说明大量 fd 属于内核匿名类型,未被 lsof 枚举。
3、对比:cat /proc/<PID>/limits | grep "Max open files",确认当前 limit 是否已被 FDs 值耗尽。

















