c-ENOENT(没有这样的文件或目录)错误发生时,我试图打开proc文件(Ubuntu)

  • 本文关键字:文件 proc Ubuntu 错误 c-ENOENT c linux
  • 更新时间 :
  • 英文 :


我正在尝试打开并读取proc/[pid]/stat文件的所有内容。

但当pid>=时,我从open func得到了ENOENT错误10961.

从过程手册页我发现:

此外,如果进程变成僵尸(已被其父进程用退出调用终止,但未被等待调用挂起(,则其大多数关联的/proc文件将从目录结构中消失。通常,稍后尝试打开或读取或写入进程终止前打开的文件会引发ENOENT消息。

但我仍然可以通过出现的路径使用cat命令查看文件的内容ENOENT

这令人困惑。这是不是僵尸的过程?为什么我不能打开它?

代码

void    get_stat(char *path)
{
int     fd;
char    *res;
printf("path : %sn", path);
fd = open(path, O_RDONLY);
if (fd < 0)
{
perror("open error");
exit(EXIT_FAILURE);
}
res = read_file(fd);
}

输出

... worked fine before 10961 ...
path : /proc/6215/stat
path : /proc/6354/stat
path : /proc/10961/stat
open error: No such file or directory
path : /proc/12049/stat
open error: No such file or directory
path : /proc/12127/stat
open error: No such file or directory
path : /proc/12168/stat
open error: No such file or directory
path : /proc/12169/stat
open error: No such file or directory
path : /proc/12171/stat
open error: No such file or directory
path : /proc/12230/stat
open error: No such file or directory
path : /proc/12238/stat
open error: No such file or directory
path : /proc/13185/stat
open error: No such file or directory
path : /proc/13284/stat
open error: No such file or directory
path : /proc/13285/stat
open error: No such file or directory
path : /proc/13466/stat
open error: No such file or directory
path : /proc/13522/stat
open error: No such file or directory
path : /proc/13523/stat
open error: No such file or directory
path : /proc/13532/stat
open error: No such file or directory
path : /proc/13579/stat
open error: No such file or directory
path : /proc/13580/stat
open error: No such file or directory
path : /proc/13589/stat
open error: No such file or directory
path : /proc/13636/stat
open error: No such file or directory
path : /proc/13637/stat
open error: No such file or directory
path : /proc/13726/stat
open error: No such file or directory
path : /proc/14416/stat
open error: No such file or directory
path : /proc/15059/stat
open error: No such file or directory
path : /proc/15153/stat
open error: No such file or directory
path : /proc/15255/stat
open error: No such file or directory
path : /proc/15571/stat
open error: No such file or directory
path : /proc/15573/stat
open error: No such file or directory
path : /proc/15603/stat
open error: No such file or directory
path : /proc/15697/stat
open error: No such file or directory
path : /proc/15744/stat
open error: No such file or directory
path : /proc/15771/stat
open error: No such file or directory
path : /proc/15790/stat
open error: No such file or directory

编辑:我用sudo命令得到了同样的结果。

我在同一个程序中通过opendir/readdir函数创建了路径字符串。它只知道现有目录。

因此,在获得路径名称时存在一些过程,然后消失并重新评估。

通过猫,我发现他们中的许多人都有"工作人员"的名字。

也许这种过程可以这样表现?我现在正在搜索。。

您需要首先检查您是否具有访问所有进程的超级用户访问权限。但是,如果您运行这个问题,我想您会得到EPERM错误
无论如何,我们无法可靠地访问/proc/中的所有文件,因为进程在系统生命周期中出现和消失。即使是您启动的程序,也会在/proc中创建一个条目,并在完成时使其消失
对于大于某个值的pid,之所以会出现错误,是因为任何新运行的进程都会得到一个递增的pid值。回滚到0之前的最大值位于/proc/sys/kernel/pid_max中。当前最后使用的pid编号是/proc/sys/kernel/ns_last_pid。此外,低pid值通常是长时间运行的进程。。。

PS:一个死进程在终止后可能仍然以僵尸状态存在,以使其终止状态可用于收割者进程,即:

  • 如果后者仍在运行(它应该通过调用wait()来获得状态(,则选择其父亲
  • 或者如果父亲死了,初始化过程

考虑下面的程序,其中一个进程创建一个子进程。后者终止(它仅调用exit(2)(。但是父进程并没有收获它,因为它进入了一个调用pause():的无限等待

#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main(void)
{
if (fork()==0) {
// child process
exit(2);
}
pause();
return 0;
}

编译并在后台运行:

$ gcc pf.c -o pf
$ ./pf &
[3] 29979

ps命令仍然显示子进程(pid=29980(,该进程已停止:

$ ps -ef
[...]
xxx     29979   17898  0 20:19 pts/0    00:00:00 ./pf
xxx     29980   29979  0 20:19 pts/0    00:00:00 [pf] <defunct>
xxx     29983   17898  0 20:20 pts/0    00:00:00 ps -ef

内核等待父进程来获取进程,但由于后者无限期地等待,因此它不执行该工作(通过调用wait()进行状态收集(。因此,子进程处于僵尸状态(stat文件第三个字段中的Z字母(:

$ cat /proc/29980/stat 
29980 (pf) Z 29979 29979 17898 34816 29991 4227140 18 0 0 0 0 0 0 0 20 0 1 0 3701092 0 0 18446744073709551615 0 0 0 0 0 0 0 0 0 0 0 0 17 3 0 0 0 0 0 0 0 0 0 0 0 0 512

如果您杀死父进程,子进程将附加到init进程,init进程将获取它。同时,如果您的程序试图读取stat文件,它可能会遇到ENOENT错误,因为收割者执行状态收集并触发删除/proc条目。

注意waitpid()的手册在";NOTES";区段:

一个终止但尚未等待的子级变成";僵尸";。内核维护关于僵尸进程的最小信息集(PID、终止状态、资源使用信息(,以便允许父进程稍后执行等待以获得关于子进程的信息。只要僵尸没有通过等待从系统中删除,它就会占用内核进程表中的一个插槽,如果这个表填满了,就不可能创建更多的进程。如果父进程终止;僵尸;init(8(采用了children(如果有的话(,它会自动执行等待以移除僵尸。

最新更新