- 打开编译选项
makefile:g++ -g -O0
cmake:set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0")
- 常用命令
使用GDB打印/查看大型代码库文件中的变量,可以按照以下步骤进行:
首先,确保已经安装了GDB调试器,并且代码库已经编译为可调试的可执行文件。
打开终端,进入代码库所在的目录,并运行可执行文件的命令。
在终端中输入gdb 可执行文件名,进入GDB调试环境。
在GDB命令行中,可以使用以下命令来打印/查看变量:
使用break 行号或break 函数名设置断点,以便在特定位置停下来查看变量。
使用run命令运行程序,直到遇到断点位置。
使用print 变量名命令打印变量的值。
使用display 变量名命令持续打印变量的值,每次程序停下来都会显示。
使用info locals命令查看当前作用域内的所有局部变量。
使用info globals命令查看全局变量。
使用info variables命令查看当前作用域内的所有变量。
使用backtrace命令查看函数调用栈,可以查看函数调用关系。
使用step命令逐行执行代码,并进入函数内部。
使用next命令逐行执行代码,但不进入函数内部。
使用continue命令继续执行代码,直到下一个断点或程序结束。
在GDB调试环境中,可以根据需要重复执行上述命令,以查看和调试代码库中的变量。
- 进阶命令
(gdb) info proc mappings
(gdb) disassemble 0x7e9f476000
(gdb) info symbol 0x7e9f476000
(gdb) x/32x 0x7e9f476000
# gdb -p pid
# detach
# 查看局部变量
info locals
# 查看全局变量
info variables
# 查看当前位置
where
# 查看当前代码
list
# 设置断点
break test.cpp:11
break main
break test.cpp:main
# 运行到断点
continue(如果没有断点则程序一直运行,停止运行用ctrl+c)
# 打印断点处变量值
print i
# 查看断点
info breakpoints
info break 1
# 删除断点
delete 1
delete(取消所有断点)
# 下一语句
next
# 下一步
step
# 列出所有函数
info functions
# 列出指定类的所有函数
info functions MyClass
# run
1. 新实例启动:当你在 GDB 中使用 run 命令时,GDB 会创建一个新的进程来运行你指定的程序。这意味着原来的程序(如果它是通过 gdb -p <pid> 附加的)将不再运行,因为 GDB 现在控制的是一个新的进程。
2. 附加与运行的区别:
附加:使用 gdb -p <pid> 附加到一个正在运行的程序时,GDB 会暂停该程序并允许你进行调试。此时,程序的状态保持不变。
运行:使用 run 命令时,GDB 启动一个新的程序实例,原来的程序(如果是通过 gdb 附加的)将被终止。
调试会话:如果你希望调试一个已经在运行的程序,应该使用 gdb -p <pid> 来附加到该进程,而不是使用 run 命令。
# set print frame-arguments all
用于设置调试器在打印栈帧信息时显示所有函数参数的值。
具体来说,这个命令的作用如下:
打印所有参数:当你在 GDB 中查看当前栈帧或调用栈时,使用这个命令可以让 GDB 显示当前函数的所有参数,而不仅仅是某些特定的参数。
调试便利:这对于调试复杂的函数调用非常有用,尤其是在函数参数较多或参数类型较复杂的情况下,可以帮助开发者更好地理解程序的状态。
使用这个命令后,当你使用 backtrace 或 frame 命令查看栈帧时,GDB 会显示所有参数的值,帮助你更好地分析程序的执行情况。
# g++ -g -o0 *.cpp -o test_thread -pthread
不使用-g在gdb调试时没有文件源码信息
# g++ -fsanitize=address -g your_program.cpp -o your_program
是一个编译器选项,用于启用地址消毒器(AddressSanitizer),这是一个用于检测内存错误的工具。它可以帮助开发者发现以下几种常见的内存问题:
1. 越界访问:检测数组或缓冲区的越界读写。
使用后释放:检测对已经释放的内存的访问。
3. 内存泄漏:检测未释放的内存,帮助识别内存泄漏问题。
双重释放:检测对同一内存块的多次释放。
使用 -fsanitize=address 编译程序时,编译器会插入额外的检查代码,以便在运行时捕获这些错误。这样可以在开发和测试阶段更早地发现潜在的内存问题,从而提高代码的稳定性和安全性。
- 查看是否包含调试信息
1)如果输出中有 .debug_* 段,表示包含调试符号
readelf -S /path/to/executable | grep debug
objdump -h /path/to/executable | grep debug
2)如果输出中有未被剥离的符号(即没有 "U" 标记的符号),则可能包含调试信息
nm /path/to/executable
注:
objdump:
用于显示二进制文件的汇编代码、符号表、段信息等。
可以反汇编可执行文件,查看其机器代码对应的汇编指令。
示例用法:objdump -d <filename> 可以反汇编指定的可执行文件。
nm:
用于列出目标文件中的符号(函数、变量等)。
可以显示符号的地址、类型和名称,帮助开发者了解程序中使用了哪些符号。
示例用法:nm <filename> 可以列出指定文件中的所有符号。
readelf:
用于显示 ELF 文件的结构和内容,包括头信息、节区、段、符号表等。
提供了比 objdump 更详细的 ELF 文件信息。
示例用法:readelf -a <filename> 可以显示指定 ELF 文件的所有信息。
- bt命令
bt 是 "backtrace" 的缩写。它用于显示当前程序的调用栈(call stack),即程序在崩溃时的函数调用顺序。
(gdb) bt
- 调试core文件
gdb 程序 core文件
(gdb) bt
注意:
1)ulimit -c unlimited
2)cat /proc/sys/kernel/core_pattern
|/usr/share/apport/apport %p %s %c %d %P %E
核心转储的生成模式被设置为通过 apport 处理。这意味着当程序崩溃时,核心转储不会直接生成为文件,而是由 apport 收集并处理,通常用于报告崩溃。
systemctl stop apport停止,或者 echo "core" | sudo tee /proc/sys/kernel/core_pattern 将核心转储的生成模式更改为默认设置
echo "core.%e.%p" | sudo tee /proc/sys/kernel/core_pattern
kernel.core_pattern = core.%e.%p(/etc/sysctl.conf)
核心转储文件格式
1. 基本格式:
core:生成的核心文件将命名为 core,并存储在当前工作目录中。
core.%e:生成的核心文件将命名为 core.<程序名>,其中 <程序名> 是崩溃程序的名称。
core.%p:生成的核心文件将命名为 core.<进程ID>,其中 <进程ID> 是崩溃程序的进程ID。
2. 组合格式:
core.%e.%p:生成的核心文件将命名为 core.<程序名>.<进程ID>。
core.%e.%p.%h.%t:生成的核心文件将命名为 core.<程序名>.<进程ID>.<主机名>.<时间戳>,其中时间戳是崩溃发生的时间。
3. 自定义路径:
/tmp/core.%e.%p:将核心文件存储在 /tmp 目录下,命名为 core.<程序名>.<进程ID>。
- python core文件示例
ulimit -c
ulimit -c unlimited
vim /etc/sysctl.conf
kernel.core_pattern = /tmp/core-%e-%p-%t
sysctl -p
python test.py
gdb python /tmp/core-python-12345-1698765432
(gdb) bt
如果段错误发生在 Python 调用的 C/C++ 扩展中,可以通过以下方式调试:
# 使用 gdb 直接运行 Python 脚本
gdb python
(gdb) run test.py
(gdb) bt
进一步调试:
gdb python
(gdb) break rknn_inputs_set
(gdb) run test.py
# 当程序停在断点时,检查参数
(gdb) print rkModel
(gdb) print io_num.n_input
(gdb) print inputs[0].buf
(gdb) print inputs[0].size
- 其它
# 清除页面缓存
sh -c "echo 1 > /proc/sys/vm/drop_caches"
# 清除目录项缓存(dentries)和 inode 缓存
sh -c "echo 2 > /proc/sys/vm/drop_caches"
# 清除页面缓存、目录项缓存(dentries)和 inode 缓存
sh -c "echo 3 > /proc/sys/vm/drop_caches"
valgrind --tool=massif ./your_program
ms_print massif.out.<pid>
heaptrack ./your_program
heaptrack_gui heaptrack.<pid>.gz
- 参考
https://www.cnblogs.com/lvdongjie/p/8994092.html
https://blog.bruceding.me/464.html