2010-10-01 81 views
1

对于类分配,我们正在编写一个自定义系统调用,它可以获取有关现有进程树的某些信息。系统调用大部分工作正常,并获得适当的信息。但是,有一些进程在崩溃时显示错误消息“无法处理虚拟地址[地址]处的内核NULL指针取消引用”。我不明白的是,我正在测试指针是否为NULL,然后它仍然失败。Linux内核编程:“无法在虚拟地址[地址]处理内核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(再次尝试几次后),它给了我一个“无法处理虚拟地址的内核分页请求”错误。据我所知,我有正确的锁定来读取这些数据。但是,在我访问内容之前还有什么需要检查内存吗?

+0

你有没有见过'parent_process'为NULL的情况?我怀疑NULL指针不是明显的指针访问,但需要更多的代码来告诉。 – nategoose 2010-10-01 20:24:41

+0

是的,我看到了parent_process为NULL的情况。例如,init进程(进程1)有一个NULL real_parent,并将进入else情况。 – achinda99 2010-10-01 20:36:13

+0

请问我们能否看到parent_process的结构声明/定义? – 2010-10-02 05:31:20

回答

1

我在这里猜测,但可能parent_process->pidNULL是你的“内核恐慌”的原因?如果是这样,你也可以检查。

它或者,或者访问数组即i th元素的问题即。 *(k_buf+i)

+0

授予parent_process似乎是有效的(见下面的评论),我倾向于parent_process-> PID为NULL。但是,在尝试访问它之前,我测试了“if(&parent_process-> pid!= NULL)”,并且仍然出现错误。 – achinda99 2010-10-01 20:39:53

+0

咦? 'parent_process-> pid'不是一个指针,那它怎么可能是NULL? – 2010-10-01 20:43:10

+0

我知道这是没有道理的,但现在,它的parent_process-> pid是抛出错误(从我的理解)。我知道它不是一个指针。现在我已经把我的头撞在墙上了。 – achinda99 2010-10-01 20:50:10

0

我有两个问题。 real_parent有什么可能的值?它可能不是NULL?你能打印这个值并检查它在内核恐慌之前是什么吗?

另外,你确定k_buf [i]正确解引用?我不确定,只是试图抛出一些想法。

编辑:我同意crypto
parent_process-> pid可能为空。

+0

在include \ linux \ sched.h中,在task_struct结构中,您会看到real_parent是指向task_struct的指针。 如果我打印parent_process的值,它会打印一些整数。所以我猜这意味着它不是NULL? 但是,如果我尝试打印parent_process-> pid,它会抛出错误并进入内核恐慌。 k_buf [i]正确解引用(通过尝试分配int并打印它进行测试)。 – achinda99 2010-10-01 20:33:22

1

在访问之前,您似乎没有测试kbufkbuf[i]。还有,你可以用printk这些指针,这样你就可以捕获到非空,但是显然无效的地址(比如0xbfff0c3a

+0

kbuf和kbuf [i]是有效的并且已经过测试。原来问题出在current_process上。它被设置的方式,在某些情况下是有效的,在其他情况下是无效的,但以某种方式超过了先前的NULL检查。 – achinda99 2010-10-07 00:08:59