Segfault只出现在GDB中

时间:2022-06-03 03:15:55

Why does the following program not crash when it is executed, but crash with a segfault in GDB? Compiled with GCC 4.5.2 on a 32-bit x86 (Athlon 64, if it should matter).

为什么以下程序在执行时不会崩溃,而是在GDB中使用segfault崩溃?使用GCC 4.5.2在32位x86(如果有用的话,可以是Athlon 64)上编译。

#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. This will probably be different on a different system. ASLR was disabled for this.

mov $0xbffff2d4, %eax是使用GDB来确定返回指针存储为“函数”函数的地址。这在不同的系统上可能是不同的。ASLR为此被禁用。

When I execute the program, nothing happens. There is no report of a crash in dmesg either. However when I execute the same program in GDB:

当我执行程序时,什么也没有发生。也没有关于dmesg坠毁的报道。但是当我在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?

这也是我希望在正常执行程序时发生的情况。当其他程序崩溃时,我确实会像往常一样得到segfault,而且我可以很容易地编写一个小程序,它崩溃时带有一个漂亮的segfault。但是为什么这个特殊的程序不会因为segfault而崩溃呢?

1 个解决方案

#1


2  

Even with full ASLR disabled, you may still get randomized stack and heap. 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. It's also part of the process personality.

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

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;
}

#1


2  

Even with full ASLR disabled, you may still get randomized stack and heap. 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. It's also part of the process personality.

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

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;
}