下面是do_signal之前和之后iret之前的内核态堆栈的变化情况,主要是原esp和原eip的变化情况。
相关代码:
void do_signal(long signr,long eax, long ebx, long ecx, long edx,
long fs, long es, long ds,
long eip, long cs, long eflags,
unsigned long * esp, long ss)
{
......
tmp_esp=esp;
put_fs_long((long) sa->sa_restorer,tmp_esp++);current->blocked |= sa->sa_mask;
}
因为: int sa_flags; 0xc0000000
#define SA_NOMASK 0x40000000
所以这一句: put_fs_long(current->blocked,tmp_esp++);不会运行,
所以用户态堆栈会压入7×4个字节。
在do_signal下断点,在task3的任务数据结构所在页面的末端,可以看出用户态堆栈为0x03ffff10,
而任务3的线性地址为64M*3-64M*4既0x0c000000,所以用户态堆栈为0x0fffff10。
此时用户态堆栈最后一个字是0x0000007b
在do_signal函数的最后下断点,可以看出用户态堆栈的7×4个字节的内容,最后一个应该是0x0000011f。