首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在linux内核中遍历进程树

问在linux内核中遍历进程树
EN

Stack Overflow用户
提问于 2011-11-21 13:54:02
回答 1查看 3.5K关注 0票数 1

我在一个内核模块中有以下代码,它遍历进程树并打印进程名称和uids,直到init进程:

代码语言:javascript
复制
// recursivly walk the task's parent until we reach init

void parent_task_walk(struct task_struct *task) {

    struct task_struct *parent;
    char filename[MAX_FILE_LEN];

    if (task && task->mm) {

        parent = get_task_parent(task);

        printk("%s (uid:%d)", exe_from_mm(task->mm, filename, MAX_FILE_LEN),
            get_task_uid(task));

        if (parent && task->pid != 1) {
            printk(", ");
            parent_task_walk(parent);
        }
    }

}

注意:我使用了一些引用真实内核函数的宏,因为这是一个跨越多个版本的内核模块。源代码在这个文件中:https://github.com/cormander/tpe-lkm/blob/319e1e29ea23055cca1c0a3bce3c865def14d3d2/core.c#L61

输出结果如下所示:

/bin/bash (uid:500), /usr/sbin/sshd (uid:500), /usr/sbin/sshd (uid:0), /usr/sbin/sshd (uid:0), /sbin/init (uid:0)

这是一个递归函数。正如您可以想象的那样,当您启动200个bash shell并触发事件时,事情会变得很糟糕。我不确定到底发生了什么,但是机器死机了。内核耗尽了堆栈空间,我猜是不是发生了OOM,然后自己射杀了自己?

我想知道处理这个案子最好的方法是什么。我看到了几个选项:

1)在N个进程后停止遍历进程树

2)在某个字符数组(最终将被打印)已满后停止遍历

3)使用goto而不是递归函数,但仍然遵循选项#1和#2中的新规则

4)使用其他一些非递归方法,您将为我阐述这些方法

这是在内核空间发生的,所以不是最友好的环境。有没有人能给出一些建议,说明解决这个问题的最佳方法?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-11-22 05:51:05

实际上,您的内核崩溃很可能是因为您正在使用递归函数。

你可以使用一个非常简单的循环来代替你的递归函数。你来自函数式编程的世界吗?while循环在C中是标准的,但是如果你真的想使用goto,你可以...;)这里是使用循环的代码。

代码语言:javascript
复制
void parent_task_walk(struct task_struct* task) 
{

    struct task_struct *parent = NULL;
    char filename[MAX_FILE_LEN];


    while (task && task->mm) {

        parent = get_task_parent(task);

        printk("%s (uid:%d)",
               exe_from_mm(task->mm, filename, MAX_FILE_LEN),
               get_task_uid(task));

        if (parent && task->pid != 1)
            printk(", ");

        task = parent;
    }

}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8207833

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档