調試的本質:確認原則。確認你認爲正確的事情確實是正確的。
node
調試的其餘原則:
express
從簡單工做開始調試。編程
使用自頂向下方法。
windows
使用調試工具肯定段錯誤的位置。數組
經過發出中斷肯定無限循環的位置。
函數
使用二分搜索。工具
調試器暫停的代碼行,其實是將要執行的代碼行。操作系統
斷點類型:斷點 監視點 捕獲點unix
設置斷點的方式:調試
break function 在函數function()入口處(第一行可執行代碼)設置斷點。
break line_number 在當前活動源文件的line_number處設置斷點。對於多行程序,這要麼是上次使用list命令查看其內容的文件,要麼是包含main()的文件。
break filename:line_number 若是filename不在當前工做目錄中,則能夠給出相對路徑名或者完整路徑名
break filename:function 重載函數或者使用同名靜態函數的程序可能須要這種形式。
tbreak是設置臨時斷點,在第一次中斷以後會自動刪除。
刪除、禁用斷點的方式:
delete breakpoint_list 刪除斷點使用數字標識符
delete 刪除全部斷點
clear 清除gdb將執行的下一個指令處的斷點。
clear function、clear filename:function、clear line_number、clear filename:line_number
disable breakpoint_list
enable breakpoint_list
查看斷點屬性:info breakpoints
標識符(Num):斷點的惟一標識符。
類型(Type):斷點的類型。
部署(Disp):下次到達斷點後,斷點上會發生什麼事情。有3種,保持(keep),刪除(del),禁用(dis)
啓用狀態(Enb):啓用仍是禁用。
地址(Address):這是內存中設置斷點的位置。
位置(What):斷點所在位置的行號和文件名。
另外還能夠查看,斷點已經到達多少次。
恢復執行:
step與next單步調試,後面能夠接受一個整數參數n,表示執行n行代碼。 根據自頂向下調試原則,應該首先使用next
continue恢復程序執行,後面能夠接受一個整數參數n,表示gdb忽略下面n個斷點。
finish 當單步進入函數,想要跳過函數的剩餘部分,可使用finish。
until 執行程序,直到它到達內存地址比當前內存地址更高的機器指令,而不是直到到達源代碼中一個更大的行號。可是until確實可以,跳過循環體,到達循環體外的下一行代碼。
事實上,until能夠接受源代碼中的位置做爲參數,就像break同樣。這樣就能夠在任何想要暫停的位置暫停程序了。
eg:until 17,until swap, until swapflaw.c:17, until swapflaw.c:swap
條件斷點:
break break-args if (condition) 其中break-args是能夠傳遞給break以指定斷點位置的任何參數。condition是布爾表達式,括號是可選的。
eg:break 180 if i < 0 && pt == NULL,break myfunc if i % (j + 3) != 0,break test.c:44 if strlen(mystring) == 0
若是在gdb中使用庫函數,而該庫不是調試符號編譯的,那麼惟一能在斷點條件中使用的返回值類型爲int。
能夠對正常斷點設置條件以將它們轉化爲條件斷點,使用condition break-num expression,取消條件則是condition break-num
斷點命令列表:
爲了實現遇到一個斷點以後,自動執行一些gdb命令,可使用斷點命令列表。
commands breakpoint-num
commands
end
breakpoint-num是斷點標示符,下一行的commands是任意的命令,end標示輸入完畢。
eg:break fibonacci
commands 1
>silent 爲了使gdb更安靜地觸發斷點,必須是第一個命令
>printf "fibonacci was passed %d.\n", n gdb的輸出命令,與c語言的語法相同
>continue 斷點以後繼續自動執行
>end
能夠將固定命令列表定義爲宏,show user能夠獲得全部宏的列表
define print_and_go
>printf $arg0, $arg1 最多擁有10個參數
>continue
>end
commands 1
>silent
>print_and_go "fibonacci was passed %d\n" n 注意參數沒有逗號
>end
gdb能夠調用源代碼中的函數:
call myfunc()
在斷點命令列表中使用,能夠避免修改源碼,這點很強大,很方便。
監視點:
它沒有住在某一行源代碼中,而是當表達式改變時,暫停程序執行。監視的變量必須存在且正處在做用域中,不然沒法設置監視點,出做用域以後,監視點也會自動刪除。
watch var
watch expression
複雜數據類型變量查看:
動態數組 int* x = (int*)malloc(25 * sizeof(int)); 格式爲:p *x@25 也能夠用強制轉換 p (int[25]) *x
結構體 struct node { int val; struct node* left; struct node* right; }; struct node* nsp; 格式爲: p *nsp
類 class node { public: static class node* root; int val; class node* left; class node* right; node(int x); static void insert(int x); static void printtree(class node* nptr); }; class node::root = 0; class node* nsp; 格式爲: p *nsp
使用ptype能夠查看結構體或類的結構,ptype node。
程序崩潰:用編程界的行話說,當某個錯誤致使程序忽然和異常地中止執行時,程序崩潰。
迄今最多見的致使程序崩潰的緣由是試圖在未經容許的狀況下訪問一個內存單元。硬件會感知這件事,並執行對操做系統的跳轉。在unix系列的平臺上,操做系統通常會宣佈程序致使段錯誤(seg fault),並中止程序的執行。在windows系統上,對應的術語是通常保護錯誤(general protection fault)。使用調試器能夠記錄崩潰調用棧。
核心文件的使用:
gdb -c core.num target
core.num 是崩潰生成的文件 target是執行的程序