这个问题搞了我好些日子了,通过看suse11内核实现源代码,一点一点排除,最终还是把它搞定了,所以把它写下来吧。
发生问题环境:
Linux内核版本:Linux linux-suse11 2.6.27.45-0.1-default #1 x86_64 x86_64 x86_64 GNU/Linux
cpu细节就不说了:是一个多处理器,有16核
应用进程是:32bit, 系统内核都是64bit
问题现象:
自己编写了一个内核模块,接管了系统的INT3中断,自己实现中断处理,但处理过程要获取本进程id,但通过current->tgid获取中断发生时本进程id时就会导致中断处理过程中出现错误,最终导致系统死掉,需要重启。
问题定位:
下面所说的都是指内核模块里面,有最高权限。
1、这个宏current->tgid在其它地方是可以访问的,就是不在中断处理函数里面,在一般函数里面是可以访问,如ioctl函数里面。
而在中断处理函数里面就会出错。
2、通过反汇编把自己编写的内核模块反汇编出来,可以看出,cur_gid = current->tgidd在ioctl函数里面和中断处理是一样的,下面是大概汇编实现代码,不是真正反汇编出来的。
mov %gs:0x0 %rax(这个%rax可以使其它通用寄存器)
mov 0xoffset(%rax), (cur_gid) (这个是把刚才获取的地址再偏移一下取的值,赋值给一个地址)
从上面可以看出,都是通过一个段寄存器gs来获取current指向当前进程控制结构体的地址,然后在获取其tgid,下面suse11下具体实现c源代码: