gdb
GDB是一个由GNU开源组织发布的、UNIX/LINUX操作系统下的、基于命令行的、功能强大的程序调试工具。 对于一名Linux下工作的c/c++程序员,gdb是必不可少的工具;
启动
gdb test
gdb -q test //表示不打印gdb版本信息,界面较为干净;
gdb [exec file] [core file]。
运行命令
命令 | 缩写 | 说明 |
---|---|---|
run | r | 运行程序,当遇到断点后,程序会在断点处停止运行,等待用户输入下一步的命令。 |
continue | c | 继续执行,到下一个断点处(或运行结束) |
next | n | 单步跟踪程序,当遇到函数调用时,也不进入此函数体;此命令同 step 的主要区别是,step 遇到用户自定义的函数,将步进到函数中去运行,而 next 则直接调用函数,不会进入到函数体内。 |
step | s | 单步调试如果有函数调用,则进入函数;与命令n不同,n是不进入调用的函数的 |
until | 当你厌倦了在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体。 | |
until + line num | 运行至某行,不仅仅用来跳出循环 | |
finish | 运行程序,直到当前函数完成返回,并打印函数返回时的堆栈地址和返回值及参数值等信息。 | |
call | 调用程序中可见的函数,并传递“参数”,如:call gdb_test(55) | |
quit | q | 简记为 q ,退出gdb |
设置断点
命令 | 缩写 | 说明 |
---|---|---|
break n | b n | 在第n行处设置断点 |
b fn1 if a>b | 条件断点设置 | |
break func | b | 在函数func()的入口处设置断点,如:break cb_button |
delete 断点号n | 删除第n个断点 | |
disable 断点号n | 暂停第n个断点 | |
enable 断点号n | 开启第n个断点 | |
clear 行号n | 清除第n行的断点 | |
info b | 显示当前程序的断点设置情况 | |
delete breakpoints | 清除所有断点 |
查看源码
命令 | 缩写 | 说明 |
---|---|---|
list | l | 列出程序的源代码,默认每次显示10行。 |
list line num | 将显示当前文件以“行号”为中心的前后10行代码,如:list 12 | |
list func | 将显示“函数名”所在函数的源代码,如:list main | |
list | 不带参数,将接着上一次 list 命令的,输出下边的内容。 |
打印表达式
命令 | 缩写 | 说明 |
---|---|---|
print 表达式 | p | 其中“表达式”可以是任何当前正在被测试程序的有效表达式,比如当前正在调试C语言的程序,那么“表达式”可以是任何C语言的有效表达式,包括数字,变量甚至是函数调用。 |
print a | 将显示整数 a 的值 | |
print ++a | 将把 a 中的值加1,并显示出来 | |
p /x a | 将显示整数 a 的十六进制值 | |
p *array@3 | 将显示数组 array 的长度为3的值 | |
print name | 将显示字符串 name 的值 | |
print gdb_test(22) | 将以整数22作为参数调用 gdb_test() 函数 | |
print gdb_test(a) | 将以变量 a 作为参数调用 gdb_test() 函数 | |
display 表达式 | 在单步运行时将非常有用,使用display命令设置一个表达式后,它将在每次单步进行指令后,紧接着输出被设置的表达式及值。如: display a | |
watch 表达式 | 设置一个监视点,一旦被监视的“表达式”的值改变,gdb将强行终止正在被调试的程序。如: watch a | |
whatis | 查询变量或函数 | |
info function | 查询函数 | |
info locals | 显示当前堆栈页的所有变量 |
查看运行信息
命令 | 缩写 | 说明 |
---|---|---|
where/bt | 当前运行的堆栈列表; | |
backtrace | bt | 显示当前调用堆栈 |
up/down | 改变堆栈显示的深度 | |
set args | 参数:指定运行时的参数 | |
show args | 查看设置好的参数 | |
info program | 来查看程序的是否在运行,进程号,被暂停的原因。 |
分割窗口
命令 | 缩写 | 说明 |
---|---|---|
layout | 用于分割窗口,可以一边查看代码,一边测试: | |
layout src | 显示源代码窗口 | |
layout asm | 显示反汇编窗口 | |
layout regs | 显示源代码/反汇编和CPU寄存器窗口 | |
layout split | 显示源代码和反汇编窗口 | |
Ctrl + L | 刷新窗口 |
多线程
命令 | 缩写 | 说明 |
---|---|---|
bt | 看函数调用栈的所有信息,当程序执行异常时,可通过此命令查看程序的调用过程; | |
info threads | 显示当前进程中的线程; | |
thread id | 切换到具体的线程id,一般切换到具体的线程后再执行bt等操作。 |
attach
- 通过命令:$ ps -aux | grep main ,获取执行main的进程(pid),例如执行main的进程为18786:
- 执行:$ gdb attach 18786,
gdb强行生成core文件
- generate-core-file
core文件生成
ulimit
-
-a : 查看当前情况
-
-c : 可以限制core文件的大小(filesize的单位为kbyte)
-
unlimited 表示core文件的大小不受限制
-
ulimit只对当前session有效
永久修改需要修改配置文件
- vim /etc/security/limits.conf
- soft * core unlimited
设置core文件路径
1.编辑环境配置文件,让shell启动时自动设置ulimit
2.更改core文件生成路径
3.sysctl配置生效
vi /etc/profile
ulimit -c unlimited > /dev/null 2>&1
vi /etc/sysctl.conf
kernel.core_uses_pid = 1
kernel.core_pattern=/tmp/core-%e-%p
sysctl -p /etc/sysctl.conf
core文件的名称和生成路径
若未设置过core文件生成路径和名称,默认生成在可执行文件运行命令的同一路径下,命名为core。新的core文件生成将覆盖原来的core文件。
1) core文件保存位置和文件名设置 通过编辑 proc/sys/kernel/core_pattern,设置文件路径和文件名,可用如下命令:
**echo "/corefile/core-%e-%p-%t" > core_pattern**
所产生的 core 文件会存放到 /corefile 目录下,产生的文件名为 core- 命令名 -pid- 时间戳
文件名参数列表说明:
%p - insert pid into filename 添加 pid
%u - insert current uid into filename 添加当前 uid
%g - insert current gid into filename 添加当前 gid
%s - insert signal that caused the coredump into the filename 添加导致产生 core 的信号
%t - insert UNIX time that the coredump occurred into filename 添加 core 文件生成时的 unix 时间
%h - insert hostname where the coredump happened into filename 添加主机名
%e - insert coredumping executable name into filename 添加命令名