我一直在寻找所有的互联网上的这个问题的答案(见主题的帖子)。我被问了两次确切的问题。一旦参加了公司的面试,并且曾经是朋友,我无法找到我的生活的答案。为什么printf()会阻止发生崩溃?
在没有调试器的情况下调试时,实际上遇到过多次这种错误,并且只是使用print语句来隔离错误。我无法回想任何确切的情况,尽管我已经体验过它。如果任何人都可以提供链接或引用,或者指向我使用print语句调试代码时可能导致错误停止的printf()源代码中的某些内容,我将非常感谢良好的阅读。
谢谢 马修Hoggan
我目前正在读所提供的链接,但进一步的谈话我已经发布了一些我弱的尝试以调查:
好了,我已经开始对自己身边玩尝试回答我自己的问题,但事情仍然没有100%清楚。以下是g ++编译器使用-S选项输出程序集而不是可执行文件的输出。等效的C++代码也在下面发布。我的目标是尝试重新创建一个简单的场景,然后尝试根据指令检测处理器级别可能发生的情况。因此,让我们在“call printf”汇编代码后面说,我假设它是从存储在/ usr/lib或另一个lib目录中的库文件链接的,我尝试访问空指针(不在代码中)或其他传统上会使程序崩溃的操作形式。我假设我将不得不找出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;
}
除了Michael Burr所说的之外,请参阅本文中有关使用printf()作为调试方法的缺点:http://www.oopweb.com/CPP/Documents/DebugCPP/Volume/techniques。html – yasouser 2011-05-21 15:41:04
谢谢你的好阅读yasouser。我之前已经应用了一些这些调试技术。如果我进行输出调试,我倾向于赞成像流一样的非缓冲输出。我现在只进行了大约3年的编程,而当我第一次启动时,遇到了“printf()”错误。 – 2011-05-23 06:00:30
另一件事是'printf'是编译器一无所知的函数调用。因此,编译器假定它可能会修改任何可能知道其地址的变量。这意味着寄存器副本在调用'printf'之前刷新并在其后重新加载。这可能会在多线程代码中导致显着的行为差异。 (它就像一个记忆障碍。) – 2011-08-26 00:13:49