C Segfault仅在GDB中显示

C Segfault仅在GDB中显示,c,linux,assembly,x86,segmentation-fault,C,Linux,Assembly,X86,Segmentation Fault,为什么下面的程序在执行时没有崩溃,而是在GDB中出现segfault时崩溃?在32位x86上使用GCC4.5.2编译(Athlon 64,如果有必要的话) 这也是我在正常执行程序时所期望的。当其他程序崩溃时,我确实会像往常一样出现segfault,我可以很容易地编写一个小程序,用一个漂亮的segfault崩溃。但是为什么这个特殊的程序不会因为segfault而崩溃呢?即使禁用了完整的ASLR,您仍然可能会得到随机堆栈和堆。您可以使用norandmaps内核引导参数全局关闭该选项,或者在运行时将/

为什么下面的程序在执行时没有崩溃,而是在GDB中出现segfault时崩溃?在32位x86上使用GCC4.5.2编译(Athlon 64,如果有必要的话)


这也是我在正常执行程序时所期望的。当其他程序崩溃时,我确实会像往常一样出现segfault,我可以很容易地编写一个小程序,用一个漂亮的segfault崩溃。但是为什么这个特殊的程序不会因为segfault而崩溃呢?

即使禁用了完整的ASLR,您仍然可能会得到随机堆栈和堆。您可以使用
norandmaps
内核引导参数全局关闭该选项,或者在运行时将
/proc/sys/kernel/randomize\u va\u space
设置为零。这也是人格过程的一部分

在GDB中,您可以使用
禁用随机化设置调整此设置:

(gdb) help set disable-randomization
Set disabling of debuggee's virtual address space randomization.
When this mode is on (which is the default), randomization of the virtual
address space is disabled.  Standalone programs run with the randomization
enabled by default on some platforms.
作为说明这一点的小型测试程序,您可以打印局部变量的地址,例如:

#include <stdio.h>

int main(int argc, char **argv)
{
    printf("%p\n", &argc);
    return 0;
}
#包括
int main(int argc,字符**argv)
{
printf(“%p\n”和&argc);
返回0;
}

每次运行程序时,0xbffff2d4是函数返回指针的地址吗?对我来说似乎不是。该地址不应该相对于某个偏移量吗?根据GDB,返回地址每次都存储在0xbffff2d4。如果我启用了ASLR,那么情况显然会改变。在不同的计算机上也会有所不同。为什么地址应该是相对于某个偏移量的呢?谢谢您的输入。我已经验证了我在打印ESP时得到了一致的地址。我不认为我看到这种行为的原因是堆栈一直在移动;然后我希望看到我并不总是得到一致的ESP值。如果你在GDB中打印它,那么你当然会得到一致的值,因为正如我所引用的,默认情况下GDB会关闭随机化。不过,我是通过实际执行程序来打印的。好的,然后给你的程序添加一些延迟(比如等待用户输入)并将GDB附加到正在运行的实例。
(gdb) help set disable-randomization
Set disabling of debuggee's virtual address space randomization.
When this mode is on (which is the default), randomization of the virtual
address space is disabled.  Standalone programs run with the randomization
enabled by default on some platforms.
#include <stdio.h>

int main(int argc, char **argv)
{
    printf("%p\n", &argc);
    return 0;
}