1.斷點類型
軟件斷點:由非法指令異常實現(軟件實現)
硬件斷點:由硬件特性實現(數量有限)
數據斷點:由硬件特性實現(數量有限)
為什么要分軟件斷點和硬件斷點呢?
軟件斷點通常是可以運行於內存中的程序,代碼加載到內存中執行,那么軟件斷點就是有效的。
對於flash中的程序執行,軟件斷點就沒有用了。此時必須依賴於硬件斷點。
這就是軟件斷點和硬件斷點使用上的不同。
軟件斷點:適用於運行於內存中的程序
硬件斷點:適用於直接在flash中運行的程序。
數據斷點:往往用來監視一段內存的,如果這段內存被訪問了(讀或寫),程序的執行立即停下來,這就是數據斷點。
2.軟件斷點的相關操作
—通過函數名設置斷點
break func_name [if var = value]
tbreak func_name [if var = value]
break和tbreak的差異:斷點有效次數的差異
break設置的斷點總是有效的(永久斷點)
tbreak設置一次有效斷點(一次性斷點)
[if var = value],如果在打斷點的時候,指明了這樣的條件,那么該斷點就變成了一個條件斷點。條件斷點只有在條件成立時,才能暫停程序的執行。
—通過文件名行號設置斷點
break file_name : line_num [if var = value]
cbreak file_name : line_num [if var = value]
操作 命令
斷點查看 info breakpoints
斷點刪除 delete 1 2 n
delete breakpoints 刪除所有斷點
斷點狀態改變 enable 1 2 n
enable breakpoints
disable 1 2 n
disable breakpoints
3.調試中常用的操作
操作 命令
變量查看 print name
變量設置 set var name = value
執行下一行代碼 next
連續執行n行代碼 next n
執行進入函數 step
強制當前函數返回 return [value] 以某個值返回當前函數
運行至當前函數返回 finish 執行完當前所在的函數,然后暫停下來
執行至目標行 until line
跳轉執行 jump line
3.硬件斷點及其應用
—當代碼位於只讀存儲器(flash)時,只能通過硬件斷點調試
—硬件斷點需要硬件支持,數量有限
—GDB中通過hbreak命令支持硬件斷點
—hbreak和break的使用方式完全一致
舉個例子:
void func()
{
*g_pointer = (int)"D.T.Software";
}
如果發現這段代碼有問題,會怎么做呢?
會直接修改代碼,然后編譯。這樣看起來可以,那有沒有更高效的辦法呢?
如何驗證,究竟是不是這行代碼引起的?(不通過重新修改代碼,然后編譯的手段)
可以通過GDB來驗證解決方案,而不是直接修改代碼。此時硬件斷點就出場了。
gdb test.out
start
//查看當前的gdb支持幾個硬件斷點
show can-use-hw-watchpoints
hreak func
info breakpoints
continue
print g_pointer
set var g_pointer = (int*)malloc(sizeof(int));
print g_pointer
continue
gdb的高效之處,就是在定位的過程中,不需要去修改源代碼,自然就不需要進行重新編譯。
小結:
GDB是GNU項目中的調試器,能夠跟蹤或改變程序的執行;
GDB能夠根據core dump回溯檢查導致程序異常結束的原因;
GDB同時支持軟件斷點、硬件斷點和數據斷點;
GDB是嵌入式開發中必須掌握的重要工具。