debugging - 为什么 printf() 会阻止崩溃的发生?

标签 debugging visual-c++

我一直在互联网上寻找这个问题的答案(见帖子主题)。我被问过两次这个确切的问题。一次是公司面试,一次是 friend 面试,我一辈子都找不到答案。

在没有调试器的情况下调试时,我实际上曾多次遇到此错误,并且仅使用打印语句来隔离错误。我不记得任何确切的情况,尽管我很肯定我经历过。如果有人可以提供链接或引用,或将我指向 printf() 源代码中的某些内容,这些内容可能会导致在使用 print 语句调试代码时停止发生错误,我将不胜感激。

谢谢你, 马修·霍根

我目前正在阅读提供的链接,但为了进一步对话,我发布了一些我试图调查的弱点:

好的,所以我开始尝试自己尝试回答我自己的问题,但事情对我来说仍然不是 100% 清楚。下面是 g++ 编译器使用 -S 选项输出程序集而不是可执行文件的输出。等效的 C++ 代码也在下面发布。我的目标是尝试重新创建一个简单的场景,然后根据指令尝试检测处理器级别可能发生的情况。所以让我们说在“调用 printf”汇编代码之后,我假设它是从存储在/usr/lib 或另一个 lib 目录中的库文件链接的,我试图访问一个 NULL 指针(不在代码中),或者其他一些传统上会使程序崩溃的操作形式。我假设我必须找出 printf 在指令方面做了什么才能更深入地了解这一点?

.file   "assembly_test_printf.cpp"

        .section    .rodata

.LC0:

    .string "Hello World"

    .text

.globl main

    .type   main, @function

main:

.LFB0:

    .cfi_startproc

    .cfi_personality 0x0,__gxx_personality_v0

    pushl   %ebp

    .cfi_def_cfa_offset 8

    movl    %esp, %ebp

    .cfi_offset 5, -8

    .cfi_def_cfa_register 5

    andl    $-16, %esp

    subl    $32, %esp

    movl    $0, 28(%esp)

    movl    $.LC0, (%esp)

    call    printf

    movl    28(%esp), %eax

    leave

    ret

    .cfi_endproc

.LFE0:

    .size   main, .-main

    .ident  "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"

    .section    .note.GNU-stack,"",@progbits

等效的 C++ 代码:

#include <stdio.h>

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

    int x = 0;

    printf ("Hello World"); 

    return x;
}

最佳答案

添加 printf() 可以改变错误行为的原因有很多。一些更常见的可能是:

  • 更改执行时间(尤其是线程错误)
  • 改变内存使用模式(编译器可能会改变堆栈的使用方式)
  • 改变寄存器的使用方式

例如,一个未初始化的局部变量可能被分配给一个寄存器。在添加 printf() 之前,未初始化的变量被使用并得到寄存器中的垃圾值(可能是先前调用 rand() 的结果,所以它真的是不确定的)。添加 printf() 会导致在 printf() 中使用寄存器,并且 printf() 总是碰巧将该寄存器设置为 0(或其他)。现在,您的错误程序仍然存在错误,但行为不同。也许这种行为恰好是良性的。

关于debugging - 为什么 printf() 会阻止崩溃的发生?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6079865/

相关文章:

debugging - 在 GDB 中设置观察点

c++ - 简单 for 循环的意外无意义优化尝试(在 Visual C++ 2017 中)

c - 小端与大端的类型转换

c++ - 尝试链接 boost::filesystem 以调试 MSVC11 项目时出现链接器错误

c++ - 单例类找不到 ctor 但编译、运行并使实例未初始化

java - 长 Java 'try' block 中的哪一行抛出异常?

Python:如何确保您的代码不会被您使用的库意外导入?

c++ - 覆盖虚拟方法时出现编译器错误

c# - 统一: GameObject repeated instantiation issue

Python 抛出 : Invalid -W option ignored: invalid module name: 'yaml'