C/C++调试
gdb调试基础
1. 介绍
linux下程序调试工具,可以基于命令行断点调试程序。
2. 入门文档
gdb tutorial
GDB调试指南
linux常用命令–开发调试篇
3. 用例
step1: 使用debug标志编译链接程序:
注意添加 -g
g++ -g hello.cpp -o hello
step2: 使用gdb运行程序
gdb hello
step3: 使用gdb命令调试程序
# 从头运行程序直到遇到断点或程序末尾
r
# 在'fun'函数开始设置断点
b fun
# 将断点设置在第N行
b N
b file.cpp:N
# 删除断点
d N
# 查看断点
info break
# 继续运行直到下一个断点
c
# 运行直到当前函数结束
f
# 运行下一行
s
# 运行接下来的N行
s N
# 类似于s,但据说不会step into (实验的时候进去了...)
n
# 打印变量的当前值
p var
# 设置变量值
set variable var=value
# 打印调用栈
bt
# 退出
q
注意:
你可能会使用set a=1
来设置变量值,但是参考这儿,由于gdb具有其他以a
开头的子命令,set
会先匹配这些子命令,导致gdb不知道该选择哪个命令,最后发生错误:
(gdb) set a=1
Ambiguous set command "a=1": .
因此设置变量最好的方式是使用variable
:
set variable a=1
# 或者
set $a=1
step4: 退出gdb
quit
4. 使用core dump调试程序
如果程序发生崩溃,例如发生段错误,为了查找崩溃原因,可以用gdb调试core文件。
参考linux下core dump【总结】。
- 判断core dump功能是否打开
ulimit -c
# 若输出0表示默认关闭
# 打开core dump 程序
ulimit -c unlimited
- 执行程序,生成core文件(打开core dump后,当程序发生崩溃时,会自动生成core文件)
./hello
- gdb调试core 文件,查看程序崩溃位置
gdb ./hello core
注意:
如果是在windows下使用docker,如果在windows和docker的共享目录下运行程序,会生成不可用的core文件(0字节)。将可执行文件移动到docker目录下运行,就可以正常生成core文件了。
cppcheck
1. 介绍
c/c++代码缺陷静态检查工具。可以检查内存泄漏,变量未初始化等问题。
可检查的问题列表参考:Checks。或者使用代码
cppcheck --doc
cppcheck --errorlist
2. 使用文档
参考:cppcheck官网
# linux 安装
sudo apt-get install cppcheck
3. 用例
# 检查源文件
cppcheck test.cpp
# 默认只显示错误信息,可以通过--enable显示其他信息
cppcheck --enable=warning,performance test.cpp
cppcheck --enable=unusedFunction test.cpp
cppcheck --enable=all
内存泄漏检测:Valgrind / jemalloc
- 另一个适用于linux内存问题查找工具Valgrind。参考这儿。
- jemalloc:这个运行速度快
- jemalloc最早用于FreeBSD(unix变体),简单的说,jemalloc分配+回收性能比较好,而且可以降低内存分配中的碎片,也可以根据自己的需要配置jemalloc内存分配相关参数(tuning,一般情况下不需要调整)
- jemalloc的Github
- 编译jemalloc动态库:
./configure --enable-prof --disable-static && make -j18
(加上enable-prof使得jemalloc能够定位heap),同时在bin目录下也会生成jeprof用于统计profile的结果。 - Jemalloc的wiki:
- jemalloc Getting-Started,其中最简单的方法是运行的时候链接
- 内存泄漏检查profile说明(相对于valgrind的优势是比较快):Leak Checking
- 内存检测的结果字段说明:https://gperftools.github.io/gperftools/heapprofile.html
内存越界检测:AddressSanitizer
addr2line
- addr2line 可以根据程序崩溃地址定位代码行