目录
注1:gdb调试值core文件临时生成,首先使用ulimit -c查看core文件大小设置,并可用该命令更改大小设置,当为ulimit -c unlimited时,core文件大小没有限制
注2:设置永久生成core文件:修改文件/etc/sysctl.conf;将#* soft core 0修改为#* soft core unlimited;使用sysctl -p生效,下次登录即可生效
一、进入调试的方式
1、直接进入gdb调试模式:gdb 可行性文件
2、先进入gdb,在加载可执行文件:先运行gdb;然后file 可执行文件,用以加载可执行文件
3、直接通过core文件进行gdb调试:gdb 可执行文件 core_file;直接将core文件和可执行文件进行关联调试
4、先加载可执行文件,再加载core文件进行调试:先gdb 可执行文件,去加载程序,然后用core-file core_file去加载生成的core_file的core文件
5、调试一个正在运行的程序:先运行程序,然后利用ps -aux | grep 可执行文件,查询程序对应的进程号PID,然后进入gdb,使用attach PID进行调试
二、单线程下的GDB
1、有条件断点:break(b) abc.c:12 if aaa==100,也可以使用condition n 条件表达式,给断点n设置执行条件
2、有参数运行:set args abc def,并可以用show args查看运行参数
3、知道地址打印对应地址的内容:print(p) /x 地址
x 按十六进制格式显示变量;
d按十进制格式显示变量;
u按十六进制格式显示无符号整型;
o按八进制格式显示变量;
t按二进制格式显示变量;
a按十六进制格式显示变量;
c按字符格式显示变量;
f按浮点数格式显示变量;
4、切换栈信息:使用:frame n(f n)n为对应的堆栈层,查看栈顶信息直接使用:frame(f)
当想向栈的上或下移动n层的时候使用:up n 或者 down n
5、查看栈或断点的信息可以使用:info f/b
6、显示源代码使用:list(l)
(1)list n:显示第n行周围源程序;
(2)list fun():显示fun()函数周围源程序;
(3)list m,n:显示m到n之间的源程序;
(4)list +/- n:往当前行前/后显示代码;
(5)list fun():查看fun()函数所在源文件和行数;
(6)list *address:查看地址所在源程序
(7)set listsize n:当想改变显示的代码行数的时候进行设置;
(8)show listsize:查看当前显示的行数设置
(9)forward-search str:从当前行向后搜索str字符串的程序行;
(10)reverse-search str:和forward-search相反,是向前查找;
7、指定源文件的路径:directory
(1)directory(dir) path:添加一个源文件到当前路径前,多个源文件可以用:分开;
(2)show directory:显示定义了源文件的路径;
8、查看源程序的内存地址:info line xxx;xxx可以为行号,函数名,文件名:函数名
9、查看源程序的汇编代码:
(1)disassemble:查看当前源代码的汇编代码;
(2)disassemble func:查看函数func的汇编代码;
10、输出变量等信息:print var;简写为p var,可以指定格式进行输出 /x;print可以用$1,$2的方式输出历史输出:p $1
11、数组:有时候在查询数组或者malloc分配的连续内存空间的值,可以使用@操作符
(1)比如int packt_num[24] = {1,2,3,4,5,6};查看值可以使用p *packt_num@len(len为查看的长度)
(2)当为静态数组的时候,可以直接p static num[]
12、自动显示:display
(1) display <expr>:expr是一个表达式
(2)display /<fmt> <expr>:fmt表示显示的格式
(3)display /<fmt> <addr>:addr表示内存地址
(4)undisplay <dnums...>:不显示dispaly
(5)delete display [dnums]:删除自动显示,不带dnums参数则删除所有自动显示,也支持范围删除,如: delete display 1-5
(6)disable display <dnums...>:使display失效
(7)enable display <dnums...>:恢复display
(8)info display :查看display信息
13、设置显示选项:set
(1)set print address on:打开地址输出,当程序显示函数信息时,GDB会显出函数的参数地址。系统默认为打开的
(2)set print array on:打开数组显示,打开后当数组显示时,每个元素占一行,如果不打开的话,每个元素则以逗号分隔。这个选项默认是关闭的
(3)set print elements:这个选项主要是设置数组的,如果你的数组太大了,那么就可以指定一个来指定数据显示的最大长度,当到达这个长度时,GDB就不再往下显示了。如果设置为0,则表示不限制
(4)set print null-stop:如果打开了这个选项,那么当显示字符串时,遇到结束符则停止显示。这个选项默认为off
(5)set print pretty on:如果打开printf pretty这个选项,那么当GDB显示结构体时会比较漂亮;该设置会让结构体更方便查看
(6)set print union:设置显示结构体时,是否显式其内的联合体数据;该设置会让结构体内的联合体也显示,更方便
(7)set print object:在C++中,如果一个对象指针指向其派生类,如果打开这个选项,GDB会自动按照虚方法调用的规则显示输出,如果关闭这个选项的话,GDB就不管虚函数表了。这个选项默认是off
(8)set print static-members:,当显示一个C++对象中的内容是,是否显示其中的静态数据成员。默认是on
(9)set print vtbl:GDB将用比较规整的格式来显示虚函数表时。其默认是关闭的
14、设置自己的环境变量:set $var=value,本方法还可以设置结构体和数组变量
15、修改程序变量值:print var1=4,意为将变量var1的值修改为4,或者set var var1=5,意为修改var1的值为5
16、查看当前设置的所有环境变量:show convenience
17、查看寄存器信息:
(1)info registers:查看寄存器情况,处理浮点寄存器,加上对应的寄存器名可以查看对应寄存器的情况
(2)info all-registers:查看所有寄存器情况
(3)p $sp:使用print来访问寄存器的情况,寄存器名字前加个$即可
18、查看变量的类型:whatis var,输出为var对应的变量类型,也可用ptype显示数据类型,但是它可以显示typedef定义的类型
19、跳转执行程序:jump,下一条程序位置可以为:文件的行号,file:line,+number
20、产生指定信号量:signal 1-29
#define SIGHUP 1 :进程由於控制终端死去或者控制终端发出起命令
#define SIGINT 2 :键盘中断所产生的信号
#define SIGQUIT 3 :键盘终止
#define SIGILL 4 :非法的指令
#define SIGTRAP 5 :进程遇到一个追踪(trace)或者是一个中断嵌套
#define SIGABRT 6 :由abort系统调用所产生的中断信号
#define SIGIOT 6 :类似於SIGABRT
#define SIGBUS 7 :进程试图使用不合理的记忆体
#define SIGFPE 8 :浮点异常
#define SIGKILL 9 :KILL
#define SIGUSR1 10 :用户自定义
#define SIGSEGV 11 :段错误
#define SIGUSR2 12 :用户自定义
#define SIGPIPE 13 :管道操作时没有读只写
#define SIGALRM 14 :由alarm系统调用产生的timer时钟信号
#define SIGTERM 15 :收到终端信号的进程
#define SIGSTKFLT 16 :堆叠错误
#define SIGCHLD 17 :子进程向父进程发出的子进程已经stop或者终止的信号
#define SIGCONT 18 :继续运行的信号
#define SIGSTOP 19 :stop
#define SIGTSTP 20 :键盘所产生的stop信号
#define SIGTTIN 21 :当运行在後状态时却需要读取stdin的资料
#define SIGTTOU 22 :当运行在後状态时却需要写向stdout
#define SIGURG 23 :socket的紧急情况
#define SIGXCPU 24 :进程超额使用CPU分配的时间
#define SIGXFSZ 25 :进程使用了超出系统规定文件长度的文件
#define SIGVTALRM 26 :内部的alarm时钟过期
#define SIGPROF 27 :在一个程式段中描绘时钟集过期
#define SIGWINCH 28 :终端视窗的改变
#define SIGIO 29 :非同步IO
#define SIGPOLL SIGIO :pollable事件发生
21、强制函数返回:return,使用return可以在函数未执行完的情况下,进行返回
22、调用函数:call和print都可以进行函数调用
23、观察变量:awatch和watch:awatch在变量或表达式发生改变或读取都会停止,但是watch只有在值改变时才停止
24、遇断点后执行特定命令:commands (n):在遇到当前断点或者第n个断点时,会执行commands后指定的命令,以end结束,当想清除commands时,直接commands然后输入end清除
25、清除断点或自动显示的表达式:delete n:n为断点号,也可以用disable和enable阻止断点或恢复断点功能,ignore n m则可以设置忽略断点n m次不执行
26、跳过当前断点继续运行:continue(c)num,类似于循环语句的continue,有num的情况下,跳过接下来的Num处断点
27、执行下一条或之后n条语句:next(n) n:执行一条语句就不加n,但是不会进入函数内部
28、单步调试并跟踪到函数内部:step
29、跳出函数调用,并打印函数返回值:finish,还具有在单步调试时,返回到单步调试之前进入的函数位置,即可跳过该函数的剩余部分未执行的代码,直接完成剩余工作,如果在递归中,则会回到递归的上一层
30、使用until恢复程序执行:until会跳出当前循环体,到达循环体外的下一个语句,或者说until是执行程序,直到达到内存地址高于当前内存地址的指令,而不是更大的行号
31、浏览之前的GDB命令:Ctrl+P,Ctrl +N
32、打开窗口界面,方便查看源代码:在gdb调试时候,加上-tui,进入后可以使用info win查看当前的focus,并用focus(fs)切换窗口,比如fs SRC:切换到源代码窗口,fs CMD:切换到命令窗口
33、查看当前源程序从哪开始:info line (fun_name)
三、多线程下的GDB
1、打印所有线程堆栈信息:thread apply all bt
2、查询当前可调式所有线程:info threads;当前调试线程ID前会有“*”标识
3、切换到对应的线程:thread threadID
4、在所有的线程上打断点:b file:num thread all;即可在所有文件的相同位置打断点
5、在某几个线程执行某一个命令:thread apply threadID1 threadID2 command
6、锁定除当前线程的其他所有线程:set scheduler-locking [off|on|step]
(1)off:不锁定任何线程,也就是所有线程都执行,这是默认值;
(2)on:只有当前被调试程序会执行。;
(3)step:在单步的时候,除了next过一个函数的情况以外,只有当前线程会执行,但是出了函数就不会锁定其他线程了,所有线程都会执行;
7、查看当前锁定线程的模式:show scheduler-locking