You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

程序疑似遗留打开文件描述符,如何用lsof查看?

如何查看程序中遗留的打开文件描述符

问题根源

你的程序之所以无法通过常规命令捕获到遗留的文件描述符,核心原因是进程生命周期太短:

  • 父进程在waitpid后直接退出,lsof或/proc文件系统的查询动作赶不上进程存活时间
  • 子进程执行execve调用ls后,ls执行完立刻退出,同样来不及被工具捕获

有效排查方案

方案1:修改代码延长进程存活时间

在父进程和子进程中添加暂停逻辑,给查询留出足够时间,修改后的代码如下:

#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>

int main()
{
    int my_fd = dup(STDOUT_FILENO);
    char *cmd[2];

    cmd[0] = "/bin/ls";
    cmd[1] = NULL;

    dprintf(2, "pid = %d\n", getpid());
    if (fork() != 0)
    {
        // 父进程暂停,等待用户输入后继续
        printf("Parent paused, press enter to exit...\n");
        getchar();
        // close(my_fd);
        waitpid(-1, NULL, WUNTRACED);
    }
    else
    {
        dup2(my_fd, STDERR_FILENO);
        // close(my_fd);
        // 子进程exec前暂停
        printf("Child paused, press enter to run ls...\n");
        getchar();
        execve(cmd[0], cmd, NULL);
    }
}

编译运行后,在弹出暂停提示时,打开新终端执行:

  • 查看父进程文件描述符:ls -l /proc/<父进程PID>/fd
  • 查看子进程文件描述符:先通过ps -ef | grep myprog找到子进程PID,再执行ls -l /proc/<子进程PID>/fd
    此时能清晰看到未关闭的my_fd。

方案2:用strace追踪系统调用

直接用strace监控进程的文件描述符相关系统调用,即使进程快速退出也能捕获完整记录:

strace -e dup,dup2,close ./myprog

输出会明确展示dup创建的文件描述符编号,以及后续是否执行了close操作,直接验证是否存在未关闭的描述符。

方案3:替换exec为长期运行的程序

把子进程要执行的/bin/ls换成/bin/sleep 60,让子进程存活60秒,足够你用工具查询:

cmd[0] = "/bin/sleep";
cmd[1] = "60";
cmd[2] = NULL;

运行后执行lsof -p <子进程PID>,就能看到继承的未关闭文件描述符。

补充说明

进程执行execve时,未设置FD_CLOEXEC标志的文件描述符会被继承。你的代码中my_fd未设置该标志,所以子进程exec后会保留这个描述符,只是因为ls执行太快才无法被常规工具捕获。

内容的提问来源于stack exchange,提问作者a k

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 15:48:18