除錯與工具

中斷點(breakpoint)

想像你在讀一份很長的家具組裝說明,然後在第 12 步貼上一張醒目的標籤,寫著「在這裡停下來,檢查一下你到目前為止組好的東西」。中斷點就正是那張標籤,只是用在執行中的程式上:你放在某一行或某個函式上的一個標記,告訴除錯器「就在這裡、在這行執行之前把程式暫停,把控制權交還給我」。程式不會飛快衝過去,而是在那個點凍住,讓你四處看看。

具體來說,你以位置來設定中斷點:一個原始碼行號(「break buggy.c:42」)、一個函式名稱(「break compute」),甚至一個原始位址。當你接著執行程式時,它會以全速正常執行,直到即將執行那一行為止——然後它停下來,除錯器告訴你是哪個中斷點命中、你在哪裡。此時程式被凍住但完好無缺:你可以印出變數、看呼叫堆疊、改變值,然後繼續。在底層,除錯器通常的做法是把那個位址上的指令換成一條特殊的陷阱指令;當 CPU 撞上它,就陷入作業系統,作業系統再通知除錯器。除錯器接著悄悄把原本的指令放回去,讓你察覺不到這次掉包。

為何重要:中斷點是在你選定的時刻檢查程式、又不會被輸出淹沒的最基本手段。技巧在於選擇放在哪裡——不是每一行都放,而是放在你懷疑事情最先出錯的邊界,這樣你才能檢查「我們到達這裡時輸入是不是就已經壞了,還是這個函式把它弄壞的?」。一種常見的進階做法是讓中斷點只在某個條件下觸發(條件中斷點),這樣你只會停在那一個重要的迭代,而不是全部一百萬次。設在一條永遠不會執行的行上的中斷點就單純永遠不會觸發——而這本身就是個有用的線索:你的程式路徑跟你以為的不一樣。

在 gdb 裡: break compute 會在函式 compute 的開頭設一個中斷點。接著 run 會執行到第一次呼叫 compute 為止、停在那裡並印出該行;從那裡你可以 print n 來看引數。在 lldb 裡命令是 breakpoint set --name compute。

在一個函式上設中斷點、執行,並在那個函式第一次被進入的瞬間停下來。

中斷點是在該行執行之前暫停、而非之後——所以它顯示的變數是進入那行時的狀態,而不是它的結果。如果你的那一行從不中斷,臭蟲可能就在於:你以為會走到的那條程式路徑其實沒有被走到。

又称
break中止點斷點