編譯時需添加-gdwarf-2和-g3兩個參數。html
加了-g3的參數後,gcc編譯的時候,會將擴展的debug 信息編譯進二進制文件裏面,包括宏定義信息。web
gdb主動生成core文件: gcore多線程
break if (condition)
例子: break if (testval > 3) (testval能夠是局部變量)app
顯示字符串所有長度ide
set print elements 0 函數
整理經常使用的gdb技巧。ui
經常使用的gdb命令...編碼
直接運行spa
gdb --args prog arg1 arg2
運行gdb後使用run命令線程
gdb prog run arg1 arg2
attach到已運行的程序
gdb --pid ${PID_OF_PROG}
ptype用於顯示Symbol的類型,示例源碼爲:
struct ABC { int val; } int main() { ABC abc; return 0; }
運行gdb:
(gdb) b 7 (gdb) r (gdb) ptype abc type = struct XXX { int val; }
ptype能夠輸出表達式的返回類型,具體介紹可參考Examining the Symbol Table。
print(p)能夠按照某種類型輸出變量的值,示例源碼以下:
struct ABC { double val; int val2; } int main() { ABC abc; abc.val = 1.5; abc.val2 = 10; void *pAbc = &abc; return 0; }
運行gdb:
(gdb) b 13 (gdb) r (gdb) p pAbc $1 = (void *) 0x7fffffffe710 (gdb) p {ABC} 0x7fffffffe710 $2 = {val = 1.5, val2 = 10} (gdb) p {ABC} pAbc $3 = {val = 1.5, val2 = 10} (gdb) p * (ABC*) pAbc $4 = {val = 1.5, val2 = 10} (gdb) p {double} pAbc $5 = 1.5 (gdb) p * (double*) pAbc $6 = 1.5 (gdb) p {int} (pAbc + sizeof (double)) $7 = 10 (gdb) p * (int*) (pAbc + sizeof (double)) $8 = 10
examine(x)能夠按照必定的格式打印內存地址處的數據,詳細文檔可參考這裏。
(gdb) x/{COUNT}{FMT}{SIZE} {ADDRESS}
{COUNT}
: 打印的數目,默認爲1。{FMT}
: 打印的格式1,默認爲上次使用的{FMT}:
{SIZE}
: 打印的字節數目,默認爲上次使用的{SIZE}:
幾個例子:
(gdb) x/a 0x401419 0x401419 <main()+113>: 0x55c3c900000000b8 (gdb) x/i 0x40138d => 0x40138d <crash(int, double)+41>: mov -0x10(%rbp),%eax (gdb) x/1fg 140737488346064 0x7fffffffdbd0: 10.125
參考Specifying Source Directories,使用dir /path/to/your/sources
可在調試時添加一個源碼目錄。
gdb默認使用utf-8編碼,能夠使用以下命令修改編碼。
set charset GBK
也可直接在~/.gdbinit裏設置。
下面是一些調試多線程程序時經常使用的命令:
info threads
得知一些不太廣爲人知的技巧...
gdb調試的時候能夠從單獨的符號文件中加載調試信息。
(gdb) exec-file test (gdb) symbol-file test.debug
test是移除了調試信息的可執行文件, test.debug是被移除後單獨存儲的調試信息。參考stackoverflow上的一個問題,能夠以下分離調試信息:
# 編譯程序,帶調試信息(-g) gcc -g -o test main.c # 拷貝調試信息到test.debug objcopy --only-keep-debug test test.debug # 移除test中的調試信息 strip --strip-debug --strip-unneeded test # 而後啓動gdb gdb -s test.debug -e test # 或這樣啓動gdb gdb (gdb) exec-file test (gdb) symbol-file test.debug
分離出的調試信息test.debug還能夠連接回可執行文件test中
objcopy --add-gnu-debuglink test.debug test
而後就能夠正經常使用addr2line等須要讀取調試信息的程序了
addr2line -e test 0x401c23
更多內容可閱讀GDB: Debugging Information in Separate Files。
將內存數據拷貝到文件裏
dump binary value file_name variable_name dump binary memory file_name begin_addr end_addr
改變內存數據
使用set命令
經常使用的gdb操做,好比打斷點等能夠放在一個gdb腳本里,而後使用時導入便可。例如:
b main.cpp:15 b test.cpp:18
gdb運行時,使用source命令便可導入
(gdb) source /path/to/breakpoints.txt
或gdb運行時導入
gdb -x /path/to/breakpoints.txt prog
對於每次gdb運行都要調用的腳本,好比設置字符集等,能夠放在~/.gdbinit初始文件裏,這樣每次gdb啓動時都會自動調用。
有時候須要gdb執行若干條命令後就當即退出,而不是進入交互界面,這時能夠使用-batch
選項。
gdb -ex "set pagination 0" -ex "thread apply all bt" -batch -p $pid
上面的命令打印$pid進程全部線程的堆棧並退出。
參考gdb/Define,能夠在gdb中自定義命令,好比:
(gdb) define hello (gdb) print "welcome" (gdb) print "hello $arg0" (gdb) end
而後如此調用
(gdb) hello world
便可輸出
(gdb) $1 = "welcome" (gdb) $2 = "hello world"
在條件斷點裏能夠調用標準庫的函數,好比下面這個:
# 若是strA == strB,則在斷點處暫停 (gdb) b main.cpp:255 if strcmp(strA.c_str(), strB.c_str()) == 0 # 仍是上面的場景,直接用string類的compare函數 (gdb) b main.cpp:255 if strA.compare(strB) != 0
gdb的stl調試方法:
source ./stl-views-1.0.3.gdb STL的GDB的調試配置 STL的gdb調試命令: Data type GDB command std::vector<T> pvector stl_variable std::list<T> plist stl_variable T std::map<T,T> pmap stl_variable std::multimap<T,T> pmap stl_variable std::set<T> pset stl_variable T std::multiset<T> pset stl_variable std::deque<T> pdequeue stl_variable std::stack<T> pstack stl_variable std::queue<T> pqueue stl_variable std::priority_queue<T> ppqueue stl_variable std::bitset<n>td> pbitset stl_variable std::string pstring stl_variable std::widestring pwstring stl_variable pmap var left_var_type right_var_type pmap (*(CRoleItemAbility*)pRole.m_pItemAbi).m_uNormalPack.m_vItemMap TITEMPOS CUnitItem*