您的位置:首页 > 其它

详细的gdb调试流程

2016-07-02 10:04 176 查看
总结下gdb调试流程,当日志用。

流程:

1)带着调试选项编译(加-g),构建调试对象a.out($g++ -Wall -o2 -g ./a.cpp,如果使用到TSD等还需要加编译选项-lpthread)

2.1)启动gdb(开始运行指定程序并调试$gdb ./aout、attach到正在运行的进程并调试$gdb -p `pidof a.out`,gdb -tui分屏显示源代码)

2.2)source ./mygdbinit (载入gdb命令脚本文件mygdbinit,等效$gdb --commonds=./.mygdbinit)

2.3)开始gdb(run:直接运行、start:设置main断点再运行,start 10 20 30:发送3个参数给执行程序的main函数)

3.1)设置断点(一般<函数、行、地址、下行、偏移量、汇编机器指令行等>断点、内存断点、条件断点等:b,watch,awatch,rwatch,注意区别:b fun和b *fun的不同)

3.2)显示所有断点(info b)

3.3)删除断点(delete 断点编号、clear 详细断点、delete:删除所有断点,等)

4.1)显示栈/栈帧(bt、bt N、bt -N、bt full、bt full N、bt full -N等,注:一个进程对应call-stack调用栈,一个函数对应stack-frame栈帧,显示栈帧:info frame,)

4.2)显示汇编代码(显示指定函数的反汇编代码:disas main、disas funname,)

5.1)显示值(pc命令行、ebp栈底指针、esp栈顶指针,以及各种寄存器值,struct结构变量值、Json结构变量值、一般变量variable值,class/struc结构对象指针this,再特殊的结构变量可以自己写gdb命令脚本来显示等)

5.2)显示指定程序地址的源代码(list <*addr>:x/i $pc,list *$pc等)

5.3)显示指定行货函数的源代码(list filename:lineNum,list filename:funname,多文件时必须加文件名)

5.4)列出指定区域的代码(list line1Num, line2Num)

5.5)显示main函数的参数列表(show args)

5.6)显示info命令的其他使用(显示寄存器:info reg,显示三个寄存器的value:info r rbp rsp rip,显示当前函数的栈帧信息:info frame,显示当前调用文件的信息:info source,显示当前运行进程的信息:info proc,显示所有gdb设置:info set,显示当前所有的线程:info threads,显示所有的type名:info types,显示程序的输入参数列表信息:info args、显示当前代码块内部的局部变量:info local,显示所有自动显示设置:info
desplay,info files、info proc mapping等)

5.7)显示当前绝对路径(pwd)

5.8)显示可执行文件的所有内存段起始范围(info file)

5.9)addr2line(由代码命令行地址 得到 代码命令行源代码)

6.1)改变变量值(set:修改指定variable的值)

6.2)修改main函数的参数列表(set args 11 12 13)

7)继续执行(next、step、nexti、stepi,jump、return、call、continue、finish、until:代码级别执行,汇编级别执行,进入callee内部执行、跳跃式执行finish/until:untile addr执行到"addr"后暂停)

8.1)查找gdb命令(complete:列出所有gdb命令,complete a:列出所有a开头的gdb命令等)

8.2)gdb命令行查看(ctrl-n看次新gdb命令、ctrl-p逐个看gdb的历史命令)

8.3)在当前文件查找表达式(search a:在当前文件向下查找指定变量a或者表达式a,注:reverse-search a:是向上查找)

8.4)将当前目录下的dir1子目录放入被搜索目录群中(dir dir1)

8.5)进入dir1(cd dir1)

9.1)讲一个信号发送给正在运行的程序(single 0 等效于 continue)

10.1)附着到指定进程(attach 1920、attach `pidof ./other.out`)

10.2)切换到指定线程(thread 20167或者t 20167)

11)终止一个正在调试程序(kill命令)

注:

1)在带着调试选项(-g)编译时,在需要查看变量详细数值时,不要加优化选项,如-o2等。

如果加了优化现象进行编译,可能在gdb调试时显示值时出现<optimized out>的现象,这就是使用了优化选项进行编译导致的,去掉-o选项就可以正常显示数值了。

2)对于上面的mygdbinit简单的一个示例如下所示:

#mygdbinit
b 'main.cpp':main #文件名要用单引号括起来''
commands
silent
printf "hello worl" #此处打印一句话,还可以显示信息、设置变量值等等各种gdb命令操作,如下
printf "rbp=%p\n", $rbp #64位的时rbp,32位的机器可能是ebp
printf "rsp=%p\n", $rsp
printf "rip=%p\n", $rip	#显示当前命令行的存储地址
continue
end


3)虽然nm、objdump、strace、pstack、pstree、ptrace、top、ps、ulimit、env MALOC_CHECK_=1、flint、valgrind、mtrace、lsof、pidstat、perf(record,top、report、list等)等等,这些虽然不是gdb命令,但是都是优化程序、调试程序的好工具,后续会增加文章进行简介。

4)应该漏掉的其他的gdb流程。

5)如果熟悉了以上流程,最明显的一个效果是:发现以前加printf-->编译---->运行---->信息不够再加printf/或者设置新的变量值--->再编译-->再运行,这样的操作是很快被放弃。

(完)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: