简体   繁体   English

Segfault仅在GDB中出现

[英]Segfault shows up only in GDB

Why does the following program not crash when it is executed, but crash with a segfault in GDB? 为什么以下程序在执行时不会崩溃,但在GDB中崩溃时会出现段错误? Compiled with GCC 4.5.2 on a 32-bit x86 (Athlon 64, if it should matter). 在32位x86(Athlon 64,如果它应该重要)上使用GCC 4.5.2编译。

#include <stdio.h>
#include <string.h>

int modify(void)
{
        __asm__("mov $0x41414141, %edx"); // Stray value.
        __asm__("mov $0xbffff2d4, %eax"); // Addr. of ret pointer for function().
        __asm__("mov %edx, (%eax)");
}

int function(void)
{
        modify();

        return 0;
}

int main(int argc, char **argv)
{
        function();

        return 0;
}

The mov $0xbffff2d4, %eax was determined using GDB to find the address where the return pointer was stored for the "function" function. mov $ 0xbffff2d4,%eax是使用GDB确定的,用于查找为“function”函数存储返回指针的地址。 This will probably be different on a different system. 在不同的系统上,这可能会有所不同。 ASLR was disabled for this. ASLR因此而被禁用。

When I execute the program, nothing happens. 当我执行程序时,没有任何反应。 There is no report of a crash in dmesg either. dmesg也没有关于崩溃的报告。 However when I execute the same program in GDB: 但是当我在GDB中执行相同的程序时:

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
=> 0x41414141:  Cannot access memory at address 0x41414141

This is what I expect should happen when I execute the program normally as well. 这是我期望在我正常执行程序时应该发生的事情。 I do indeed get segfaults as usual when other programs crash, and I can easily write a small program that crashes with a nice segfault. 当其他程序崩溃时,我的确会像往常一样得到段错误,而且我可以轻松编写一个崩溃的小程序,其中有一个很好的段错误。 But why does this particular program not crash with a segfault? 但为什么这个特定的程序不会因为段错误而崩溃?

Even with full ASLR disabled, you may still get randomized stack and heap. 即使禁用了完整的ASLR,您仍然可以获得随机堆栈和堆。 You can turn that off globally using the norandmaps kernel boot parameter or at runtime by setting /proc/sys/kernel/randomize_va_space to zero. 您可以使用norandmaps内核引导参数全局关闭它,也可以在运行时通过将/proc/sys/kernel/randomize_va_space设置为零来关闭它。 It's also part of the process personality. 它也是流程个性的一部分。

In GDB, you can tweak this using the disable-randomization setting: 在GDB中,您可以使用disable-randomization设置调整它:

(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.

As a small test program to illustrate this, you can print the address of a local variable, such as: 作为一个小型测试程序来说明这一点,您可以打印局部变量的地址,例如:

#include <stdio.h>

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM