读《软件调试的艺术》对GDB相关内容的笔记整理。
【缩写】 p print
n next
s step
r run
b break
bt backtrace
c continue
i b info break
cond condition
dis disable
ena enable
【监视点】 watch (m>25) (只有遍历所在的内存值发生变化,且满足条件是中断)
【打印变量】 print j
【查看栈帧】 frame 1 (当前栈帧为0,上一个为1,依次类推)
up 上一个
down 下一个
backtrace 所有栈帧集合
【帮助文档】 help breakpoint 产看断点帮助文档
【编译时-g选项】 如果不加同样能够调试,不过不可以查看变量和行号
注意是编译过程使用,在链接过程没没有用
【tui界面】 ctrl+x+a 切换界面
【挂起正在运行的程序】 ctrl+c(如果要继续同样是continue)
【条件断点】 condition 1 num==5 (注意这里的1是断点编号,通过info b查看)
上行是将普通断点1加上条件,如果要去掉条件:condition 1 即可
break 30 if num==5 (注意这个是break将第30行直接设为条件断点)
【段错误】 数组越界或使用错误的指针
【启动文件】 gdb -command=z filename
表示调试filename可执行文件之前先从z文件中读取命令
可以将调试信息保存在源文件目录下的.gdbinit文件中(即z文件)
【临时断点】 tbreak 10
【取消确认询问】 set confirm off
【禁用/启用断点】 disable/enable (注意:enable once 和 tbreak 区别)
【结束当前栈帧】 finish (注意:无视断点,直到当前函数返回到调用处)
【until】 until 是执行程序,直到内存地址比当前地址更高的机器指令
【断点命令列表】 command 1 (1为断点编号)
silent (为了安静的输出)
printf “num is %d\n” n
continue (一行接着一行的输出,直到循环结束)
end
【call命令】 command 2
printf “call the print function”
call PrintTree(root);
(注意:这里直接调用源文件中有但没有在此处调用的函数
并传入实参进行调用!)
end
【查看数组】 静态数组(栈):p arr
动态数组(堆):p *arr@num (num为数组元素个数)
【显示变量结构】 ptype Node
【设置变量】 set num=1
set args 1 2 (设置输入参数分别为1和2,下次run时使用)
【永远不要退出GDB】 调试时同时打开三个窗口:一个GDB、一个编辑器、一个编辑器命令:
如在vim中输入:make可以编译文件
【多线程调试】 info threads (显示所有线程)
thread num (切换线程)
bt (显示栈帧)
break 35 thread 3 if x==y (线程3在第25行中断)
【并行编程一:消息】 消息由于要读内存,所以一般是网络上使用,
(方法:MPI,示例-P136) 其实socket就是消息。
【并行编程二:共享内存】 其实线程通信使用的全局变量(在数据段)和进程间通信
(方法:OpenMP,示例-P2143) 使用共享内存是一个道理,所以真正的共享内存环境中,
通常都是用多线程进行开发的!
【附加GDB调试】 对于一个已经在运行的程序,我们通过ps ax命令查看到之后,
可以直接使用: gdb+进程名+pid 的方式进行调试
而且退出gdb也不会是该进程退出!
【core文件】 程序发生段错误时,如果不能找到具体位置,可以使用core文件。
1.ulimit -a(或ulimit -c)查看core文件大小,默认为0,不能写core文件
2.ulimit -c unlimited 进行修改
3.编译时使用-g选项
4.无论是直接运行还是调试运行都可以将堆栈调用情况保存到core文件中
(但我现在的server程序在通过gdb调试时就无法生成core文件?)
5.core文件默认保存到可执行文件路径下,名为core.xxxx
6.通过gdb ./a.out core.xxxx 对core文件进行调试
7.where命令查看崩溃位置,bt查看堆栈,frame查看栈帧等。