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

Linux驱动遍历init子进程获取PID出现异常值的问题求助

问题分析与解决

核心错误点

  1. 链表成员匹配错误
    父进程的children链表挂载的是子进程的sibling成员,而非子进程的children成员。你在调用list_first_entry/list_last_entry时,第三个参数传入了children,导致结构体指针偏移计算错误,访问到无效内存,从而得到异常PID值。

  2. 缺少RCU保护
    real_parent和进程链表都受RCU(Read-Copy-Update)机制保护(指针带有__rcu修饰),直接访问会引发并发安全问题,可能导致野指针或数据不一致。

  3. list_next_entry用法错误
    该宏的第一个参数应为链表节点(struct list_head),而非task_struct结构体本身。

修正后的代码示例

#include <linux/sched.h>
#include <linux/rcupdate.h>
#include <linux/module.h>

static int __init ps_module_init(void)
{
    struct task_struct *p;
    struct task_struct *init_task = NULL;
    struct task_struct *child;

    rcu_read_lock();
    p = current;
    pr_info("Current process name: %s\tPID: %d\n", p->comm, p->pid);

    // 回溯到init进程(PID=1)
    for (p = rcu_dereference(p->real_parent); ; p = rcu_dereference(p->real_parent)) {
        pr_info("Parent process name: %s\tPID: %d\n", p->comm, p->pid);
        if (p->pid == 1) {
            init_task = p;
            break;
        }
    }

    // 遍历init的所有子进程
    pr_info("--- Init's children ---\n");
    list_for_each_entry_rcu(child, &init_task->children, sibling) {
        pr_info("Child process name: %s\tPID: %d\n", child->comm, child->pid);
    }
    rcu_read_unlock();

    return 0;
}

static void __exit ps_module_exit(void)
{
    pr_info("PS module exited\n");
}

module_init(ps_module_init);
module_exit(ps_module_exit);
MODULE_LICENSE("GPL");

更优实现方法

  1. 直接获取init进程
    无需从current回溯,内核提供全局变量init_task(对应PID=1的进程结构体),可直接使用,减少冗余代码。

  2. 安全遍历所有进程
    若要打印系统所有进程,推荐使用for_each_process()宏(需包含<linux/sched/signal.h>),它会自动处理锁与遍历逻辑:

rcu_read_lock();
for_each_process(p) {
    pr_info("Process: %s\tPID: %d\n", p->comm, p->pid);
}
rcu_read_unlock();

注意:for_each_process()在新内核中依赖RCU保护,必须包裹在rcu_read_lock()/rcu_read_unlock()代码块中。

  1. 遵循内核编程规范
  • 访问RCU保护的指针或链表时,必须持有RCU读锁;
  • 避免手动计算结构体偏移,优先使用内核提供的list_for_each_entry_rcu等宏,降低出错概率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 21:45:35