繁体   English   中英

Linux 内核编程:“无法处理虚拟地址 [地址] 处的内核空指针取消引用”

[英]Linux Kernel Programming: “Unable to handle kernel NULL pointer dereference at virtual address [address]”

对于类分配,我们正在编写一个自定义系统调用,它提取有关现有进程树的某些信息。 系统调用在大多数情况下都可以正常工作并获取适当的信息。 但是,一些处理它时会崩溃并显示错误消息“无法处理虚拟地址 [地址] 处的内核 NULL 指针取消引用”。 我不明白的是,在访问指针之前,我正在测试指针是否为 NULL,但它仍然失败。

示例:在下面的代码中,current_process 是指向 task_struct 的有效指针,k_buf 是有效的

printk("Setting parent process\n");
parent_process = current_process->real_parent;
printk("Parent process set\n");
if (parent_process != NULL) {
printk("Parent process is not null and getting pid\n");
    k_buf[i].parent_pid = parent_process->pid;
} else {
    k_buf[i].parent_pid = 0;
}
printk("Done with parent process\n");

运行时,程序打印:

Setting parent process
Parent process set
Parent process is not null and getting pid
Done with parent process

几次,然后

Setting parent process
Parent process set
Parent process is not null and getting pid

在抛出错误并进入内核恐慌之前。

我做错了什么? 有什么想法吗?

编辑:

目前,我注释掉了上面的代码,以便我可以继续处理系统调用的其余部分。 当我尝试访问子进程的 pid 时(在几次成功尝试后再次尝试),它给我一个“无法在虚拟地址处理内核分页请求”错误。 据我所知,我有正确的锁来读取这些数据。 但是,在访问内存之前,我还需要做些什么来检查内存吗?

我在这里推测,但是parent_process->pidNULL是否会导致您的“内核恐慌”? 如果是这样,你也可以检查一下。

要么是那个,要么是访问k_buf数组的第i个元素的一些问题,即。 *(k_buf+i)

你似乎并不被测试kbufkbuf[i]访问之前。 此外,您可以printk这些指针,这样您就可以捕获非空但明显无效的地址(例如0xbfff0c3a

我写了一个系统调用来列出所有进程并收到此错误

[260.613411]BUG:无法在 0000000000000040 [260.613416] PGD 0 P4D 0 [260.613422] Oops: 0000 [#1] SMP PTI6 [14] PTI3 12 CPU: 10000000000000040 处处理内核空指针取消引用:0000 [#1] SMP PTI6 13 CPU: 4 3 2 4 3 2 3 4 3 3 4 0 0 OE 4.19.5 #2

我正在检查,如果(进程->父)然后打印它的 PID,

现在我想我应该尝试 if(process->parent !=NULL)

问题的答案:亲爱的兄弟,您可以尝试使用 ppid = task_pid_nr(child_process->parent) 来获取父进程的 pid ......!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM