编译时需添加-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*