1、基本用法
在gcc/g++参数里加上 -g ,生成的文件会包含调试程序,不加该参数则不包含调试程序,不利于gdb调试。
基本命令:
list或者l :显示调试对象的代码文本内容。l 文件名:行数 可以显示该文件的第几行
b:设置断点。例如:b main ,在函数的main处设置断点。b+文件名:行数,在该文件的第几行设置断点。
i b :查看断点信息,i 的全称是 info。
r:执行程序命令,会在断点出停下来。输入n或next命令,会继续执行,只执行一行,一行一行执行。
p 变量名:表示在调试过程中,显示变量的值,p表示print的意思。
c:表示继续执行,该命令会在下一个断点处停下来。
p locals:表示显示全部的当地变量值。
基本用法为:启动调试、设置断点、查看变量、继续执行。
2、启动调试
1、启动gdb并传递参数:
方式一:gdb --args 可执行文件名 参数1 参数2 ...
方式二:使用“ gdb 可执行文件名 “启动调试,在程序还没有 r 之前,使用命令:set args 参数1 参数2 ...
方式三:使用“ gdb 可执行文件名 “启动调试,在使用 r 命令的同时加上参数,即:r 参数1 参数2 ...
2、附加到进程:
当你想调试某个程序,然而该程序已经开始运行的时候,我们不用结束该程序,再使用gdb重新运行一次,而是直接在该进程中进行gdb调试。
首先使用命令: ps -aux | grep sec 来查看进程的pid号
方式一:gdb attach <pid> 也即,已经执行的函数程序的pid号,使用命令时不用加<>括号
方式二:gdb --pid <pid>
在使用上述命令进入条时候,会进入程序的等待响应处,你可以在原进程端口输入激励条件,也可以在gdb端口输入。
在推出gdb的时候,使用命令 detach 剥离程序,然后就可以使用 q 退出gdb。
3、单步执行
单步进程调试 n 或者 next ,遇到函数调用会自动跳过函数调用。
单步进程调试 s 或者 step ,遇到自函数会进入子函数。
如果我们不想执行子函数了,使用命令 finish 将会完成当前函数,并返回调用函数的下一行。
退出总结:finish:完成当前子函数,并返回调用函数的下一行
detach:剥离当前正在运行的函数的调试程序,但剥离后程序还在执行
q 或者 quit 推出gdb
4、调试断点管理
b 函数名:在该函数调用处设置断点。
b:设置断点。例如:b main ,在函数的main处设置断点。
b 文件名:行数,在该文件的第几行设置断点。
rb 部分函数名:会在全部满足该条件的函数处添加断点,该“部分函数名”也即使“正则表达式”。
b 你要设置的断点处 if 条件表达式 :这里是条件断点,只有当满足条件的时候,才会中断,适用于循环语句。
tb 你要设置的断点处:表示临时断点,只会执行一次,执行完之后该断点立刻删除。
delete 断点号 : 删除该断点,在使用该命令前,可以使用 i b 命令,查看各个断点信息以及断点号。
disable 断点号:禁用该断点,还可以恢复。
enable 断点号:启用 disable 禁用的断点
set print array on 设置数组输出格式,为竖
set print pretty 设置结构体输出格式,为竖,也即一个表达式一行。
p 变量名=内容 可以将某一个变量的值更改为你希望的内容。
5、查看与修改内存
格式:x /选项 内存地址
x 内存地址 显示该硬件地址
x /s 内存地址 显示该地址字符串内容
x /4b 内存地址 将该地址以字节方式显示出来,显示其ascii值。
6、寄存器查看与修改
有的程序没有调试符号,这时候就适用于寄存器来查看,也就是说,在编译时候没有加-g参数的话,你不能使用 命令+变量名的方式来查看修改该变量。
查看寄存器: i register 寄存器名 或者 i r 寄存器名
寄存器名字:rdi rsi rdx rcx r8 r9,分别表所主函数第1、2、3、4、5、6个参数所在的寄存器。
命令 i registers 表示显示通用寄存器
命令 i all-registers 表示显示所有寄存器,包括浮点等寄存器
可以使用命令:set $rip=某地址 来修改函数的执行位置,rip寄存器即为指令取址寄存器pc
总结:使用命令 : info line 行数 来查看某一行的起始地址,然后可以使用命令: set $rip=起始地址来控制程序执行的位置
7、源代码查看与管理
查看源代码
显示源代码:list or l
设置每次显示的行数:set listsize 数字
查看指定函数代码:list 函数名
查看指定文件指定行代码:list 文件名:行数
往前显示: l -
如果类与子类中有相同名字的函数: l 类名::函数名
而如果此时我们不加类名,直接用:l 函数名
搜索源代码
1、search 正则表达式,例:search test
命令:forward-search test
按下回车键后,会往下查找一个符合的函数,继续按回车,继续查找下一个。
2、如果希望从后向前查找,需要使用命令:reverse-search test
如果我们继续按回车,就会继续从后向前查找
3、我们使用gdb查找函数时候的目录,一个是当前目录,一个是工作目录
使用:show directories 显示工作目录与当前目录
而当你使用了从别处拷贝过来的工程时候,因为你的工作目录与当前目录与之前的可能不一样所以没办法调试,
这个时候我们应该添加搜索目录,命令: directories 路径
8、Core dump分析
对活着的程序进行core dump 分析:
生成core dump 文件,需要对正在运行的程序进行attach,然后使用命令:gcore <core dump文件名>
对崩溃的进程分析:
在ununtu 22.04中,coredump文件生成的位置是:/var/lib/apport/coredump
在此之前需要将ulimint -c 设置为:ulimit -c unlimited,然后才能生成coredump文件。
使用命令:cat /proc/sys/kernel/core_pattern 会显示:
|/usr/share/apport/apport -p%p -s%s -c%c -d%d -P%P -u%u -g%g -- %E
表示生成coredump文件的是这个目录下的apport文件
使用coredump文件方法:
gdb 进程名字 coredump文件名字
如何分析崩溃的coredump文件
bt 调用堆栈,查看程序在什么地方崩溃了
使用shell命令:最前面加“!”号或者加“shell”。
查看系统栈空间:shell ulimit -a
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)