C语言使用popen循环调用lua产生很多僵尸进程,最后导致系统挂掉sh: can't fork

僵尸进程:

11063 root         0 Z    [sh]
11068 root         0 Z    [sh]
11072 root         0 Z    [sh]
11075 root         0 Z    [sh]
11078 root         0 Z    [sh]
11080 root         0 Z    [sh]
11082 root         0 Z    [sh]
11084 root         0 Z    [sh]

问题:用fclose关闭popen是错误的,会导致fd泄漏,达到一定的数量就不能再创建子进程了

解决:把fclose换成pclose关闭popen。

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
    char payload[1024] = {0};
    FILE *fp;
    fp = popen("exec /usr/bin/lua /tmp/abc.lua", "r");if (NULL == fp)
        return -1;

    fgets(payload, 1024, fp);
    if (payload[strlen(payload) - 1] == '\n')
    {
        payload[strlen(payload) - 1] = '\0';
    }
    pclose(fp);
}

If you use fclose on the pipe, you will have file descriptor leaks, since fclose will not free the file pointer in the kernel (which is created when you create the pipe since its a file).

While your testing so far hasn't shown any problems, run your program 3000 times (or how ever many file descriptors are allowed, upwards of an int I think) and watch when you will n o longer be able to create pipes.

参考:https://stackoverflow.com/questions/18318357/use-fclose-to-pipe-of-popen-is-a-serious-bug

posted @ 2022-01-29 18:37  船长博客  阅读(464)  评论(0编辑  收藏  举报
永远相信美好的事情即将发生!