【问题标题】:gcc compiler does not show segfault errorgcc 编译器不显示段错误
【发布时间】:2021-04-30 15:21:47
【问题描述】:

我在 Windows 10 笔记本电脑上使用 mingw 编译器。以下 c 代码应显示分段错误错误。但相反,它只是不显示任何内容(空输出)。

#include <stdio.h>

int main(){
    main();

    return 0;
}

我使用以下代码编译代码:

gcc filename.c

但是当我使用一些在线的 c 编译器时,它会显示分段错误。请告诉我如何获得段错误。如果没有任何错误,很难调试大代码。

相关:How to get back plain old "Segmentation fault" message in windows?

【问题讨论】:

    标签: gcc segmentation-fault mingw


    【解决方案1】:

    让我们看看程序集: -O0:(没有优化,gcc,只是有点剥离):

    main:
        pushq   %rbp #Push address to stack
        movq    %rsp, %rbp
        movl    $0, %eax
        call    main
        movl    $0, %eax
        popq    %rbp
        ret
    

    你只是递归地调用一个函数,总是将返回地址压入堆栈。但是在一些实现/平台定义的调用次数之后,还有另一个内存。您只需覆盖它或访问无效内存。 (分段错误)

    你可以这样看:

    高位=======低位地址

    [stack].....[someOtherMemory]
    

    ...递归调用...

    [stack  ]...[someOtherMemory]
    

    ...递归调用...

    [stack    ].[someOtherMemory]
    

    ...递归调用...

    [stack      ]someOtherMemory]
    

    Kaboom:你访问了另一个内存,那可能是不可写/不可读的 => 崩溃

    现在,您可以使用更高的优化进行编译:-O3,示例输出,再次剥离:

    main:
        jmp main
    

    这只是一个无限循环。理论上两者都会有相同的结果。只要可观察的输出保持不变,编译器几乎可以做任何事情(参见:https://stackoverflow.com/a/46455917/13912132)。

    但在第一个,它被翻译为“字面意思”,导致撞到其他部分。但如果没有其他部件被击中,它会一直运行。

    其次,编译器可能会看到,理论上这将无限运行,因此它得到了优化。

    【讨论】:

    • 我只是想知道我的程序是否在没有输出的情况下突然终止,我该如何意识到这是分段错误? Segfault 在递归调用中非常清楚,但如果代码更复杂怎么办?
    • 调试器显示它。它显示在控制台上,一个名为 SIGSEGV 的信号被“抛出”,退出代码可能表示分段错误
    猜你喜欢
    • 2014-05-16
    • 1970-01-01
    • 2018-07-28
    • 2011-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多