这与在 32 位非 PAE Ubuntu 内核中实现NX 仿真以及何时引发 CPU 异常有关。对于 NX 仿真线以下的内存区域(即“在”仿真 NX 区域“内”:从地址 0 到程序文本段的结尾——小于此二进制 in 的 0x08049000 结束地址/proc/$pid/maps
),段错误在 EIP 之后传递已登陆实际的无效地址。对于线上的地址,故障通过报告故障的不同路径触发,而不将 EIP 向前移动到故障地址,而是停留在导致故障的“ret”指令上。
你可以在 gdb 中看到:
(gdb) x/1i $pc
=> 0x8048454 <main+64>: ret
(gdb) info reg esp
esp 0xbffff54c 0xbffff54c
(gdb) x/wx $esp
0xbffff54c: 0x41414141
您还可以看到dmesg
输出中报告故障的方式的差异。这是与“508”尝试相关的输出:
[ 585.913896] a.out[1528] general protection ip:8048454 sp:bff1e8ec error:0 in a.out[8048000+1000]
这是针对“507”的:
[ 598.999760] a.out[1531]: segfault at 414141 ip 00414141 sp bfcac2c0 error 4 in libc-2.13.so[5e7000+178000]
如果您在安装了 PAE 内核的情况下启动sudo apt-get install linux-image-$(uname -r)-pae
,并且您有一个支持 PAE 的 CPU,您将看到您所期望的行为(因为 NX 仿真将被禁用以支持硬件 NX),并且所有 4 次尝试都会出现段错误预期的 EIP。