我一直在尋找所有的互聯網上的這個問題的答案(見主題的帖子)。我被問了兩次確切的問題。一旦參加了公司的面試,並且曾經是朋友,我無法找到我的生活的答案。爲什麼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