GDB调试的学习
Posted 宇努力学习
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GDB调试的学习相关的知识,希望对你有一定的参考价值。
很早就想在好好学一学gdb了,正好最近学算法(以前一直以为干硬件不需要什么特别厉害的算法,结果现在卷起来了。大厂面试题也有复杂一些的算法了)
下面的这些命令是别的博主总结的
GDB 调试过程_gdb调试过程_麷飞花的博客-CSDN博客
工具书
GDB
1.gdb
启动gdb
2.gdb -tui
启动gdb,并且分屏显示源代码
3.gdb app
启动gdb调试指定程序app
4.gdb <program> <PID>
启动程序之后,再用gdb调试
5.gdb <PID>
启动程序之后,再启动gdb调试
6.**启动gdb之后的交互命令
file app
载入指定的程序
7.set args <var>
修改发送给程序的参数
Iist
<linenum> 行号。
<+offset> 当前行号的正偏移量。
<-offset> 当前行号的负偏移量。
<filename:linenum> 哪个文件的哪一行。
<function> 函数名。
<filename:function> 哪个文件中的哪个函数。
<*address> 程序运行时的语句在内存中的地址。
set listsize <count>
设置一次显示源代码的行数。
show listsize
查看当前listsize的设置。
break
<number> 当前的文件中某一行(假设为6)设定断点。
<number if conf> 如果conf成立,就在number行处断点。
<func> 当前的文件中为某一函数(假设为func)处设定断点。
<fileName:N> 给指定文件(fileName)的某个行(N)处设置断点:
enable/ena N:启用断点
disable/dis N:禁用断点
显示当前gdb断点信息
info breakpoints
i breakpoints
i b
print/p
1.print var
print显示变量(var)值
2.print /x var
用16进制显示(var)值
x 按十六进制格式显示变量。
d 按十进制格式显示变量。
u 按十六进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
c 按字符格式显示变量。
f 按浮点数格式显示变量。
3.print *a@10
a是一个数组,10个元素
4.print x=4
修改运行时候的变量值
其它
1.finish
执行完当前函数返回到调用它的函数
2.until/u
指定程序直到退出当前循环体
3.jump 5
跳转执行程序到第5行
4.return
强制返回当前函数
5.call <expr>
强制调用函数:
print <expr>
强制调用函数2:
【如果函数的返回值是void那么call不会打印返回值,但是print还是会打印出函数的返回值并且存放到历史记录中。】
6.kill
终止一个正在调试的程序
7.display:追踪查看具体变量值
undisplay:取消追踪观察变量
8.
watch:被设置观察点的变量发生修改时,打印显示
i watch:显示观察点
layout
layout:用于分割窗口,可以一边查看代码,一边测试。主要有以下几种用法:
layout src:显示源代码窗口
layout asm:显示汇编窗口
layout regs:显示源代码/汇编和寄存器窗口
layout split:显示源代码和汇编窗口
layout next:显示下一个layout
layout prev:显示上一个layout
Ctrl + L:刷新窗口
Ctrl + x,再按1:单窗口模式,显示一个窗口
Ctrl + x,再按2:双窗口模式,显示两个窗口
Ctrl + x,再按a:回到传统模式,即退出layout,回到执行layout之前的调试窗口。
多线程调试
(1)查看可切换调试的线程:info threads
(2)切换调试的线程:thread 线程id
(3)只运行当前线程:set scheduler-locking on
(4)运行全部的线程:set scheduler-locking off
(5)指定某线程执行某gdb命令:thread apply 线程id gdb_cmd
(6)全部的线程执行某gdb命令:thread apply all gdb_cmd
例程一
#include <stdio.h>
#include <stdlib.h>
int flag = 0;
typedef struct node
int data;
struct node *next;
list,*link;
void pp(int num)
if(flag == 1)
switch(num)
case 0:
printf("\\nError%d: Failed to malloc!\\n",num);
break;
default:
printf("\\nError: unknown error!\\n");
link create()
link ll;
if((ll = (link)malloc(sizeof(link))) == NULL)
pp(0);
return NULL;
ll->data = 0;
ll->next = NULL;
return ll;
void l_free(link ll)
link p;
while(ll)
p = ll;
ll = ll->next;
printf("free:%d\\n",p->data);
p->next = NULL;
free(p);
p = NULL;
void l_show(link ll)
link p;
p = ll;
while(p)
printf("%d",p->data);
p = p->next;
int l_in(link ll)
int *p,*p1;
link q;
link s;
q = ll;
printf("input>>> ");
scanf("%d",p);
getchar();
p1 = p;
while(p)
if((s = (link)malloc(sizeof(link))) == NULL)
pp(0);
return -1;
s->data = *p1;
q->next = s;
s->next = NULL;
p1++;
q = q->next;
l_show(ll);
return 0;
int main()
link ll;
ll = create();
l_in(ll);
l_free(ll);
return 0;
在编译文件的时候加入 -g就能进行程序调试
我记得exit也能退出的不知道为什么不行了
反正quit/q都是可以退出的,查了一下好像是版本问题,我的ubuntu18.04好像是不行
那个tui没整好不过无所谓,工具是为了方便大家使用的,而不是来扭曲我们的思想和习惯。
用他好用的地方就好了,其实我以前一直很喜欢打印来找错误,这是驱动的习惯,因为驱动不用gdb,但是驱动的实习找不到啊,只好学学软件开发的东西先找个软件实习了。
加个断点
这次就没有溢出了,因为在输入这里停了。
C继续执行,很好又溢出了
n单步执行,问题出现了,就是输入的时候就G了。
回车也是单步执行
可以tab补全还可以看之前的命令
当运行到函数的时候要按step进入函数内单步执行
不然n就是直接执行完这个函数
l可以查看后面几行程序,
p可以查看变量和函数的地址或值
info是查询,可以简写成i
i b
可以查询断点
i reg
查询寄存器
i r也可以
delete删除全部断点也可以指定删除
简写为d
Linux学习: 使用gdb和gdbserver进行调试
1.引言
在日常程序开发中不免遇到类似空指针操作导致程序崩溃的问题,所以需要一定的手段去定位bug,而断点调试是普遍使用的技巧,比如Windows中用VC++的debug模式进单步运行、断点调试等,有很友好的图形化操作界面,而在Linux中使用的是没有图形界面的调试工具-GDB(听说eclipse支持GUI调试,暂未尝试),所以需要通过指令进行操作,下面逐步介绍gdb调试环境的搭建和使用方法。
2.gdb调试环境搭建
(1)下载gdb工具源码:http://www.gnu.org/software/gdb/download/
选择下载最新版本:
注:由于个人本地arm-linux-gcc版本较低(4.4.3)不支持 C++11,后面下载编译的是 gdb7.12
(2)解压
解压tar.gz文件:tar -zxvf xxx.tar.gz
解压tar.xz文件:先 xz -d xxx.tar.xz 将 xxx.tar.xz解压成 xxx.tar 然后,再用 tar xvf xxx.tar来解包。
(3)编译安装
--------①编译gdb(在Linux主机上运行的工具)
./configure --target=arm-linux //配置要调试的目标为arm-Linux开发板(前提已经配置了arm-linux-gcc交叉编译环境) make make install //默认安装路径可以在Makefile中看到:prefix = /usr/local
也可以指定安装目录,比如 : make install prefix=$PWD/tmp
环境变量添加该路径 或 复制arm-linux-gdb到/bin目录下后便可作为系统工具使用。
错误1:
location.c:527:19: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
|| *argp == ‘ ‘
解决方法: || *argp == ‘ ‘ 修改为 || *argp == NULL
错误2:
make[5]: 进入目录“/home/sheldon/work/linux_project/gdb-8.2/gdb/doc” /home/sheldon/work/linux_project/gdb-8.2/missing makeinfo --split-size=5000000 --split-size=5000000 -I ./../../readline/doc -I ./../mi -I . -o gdb.info ./gdb.texinfo /home/sheldon/work/linux_project/gdb-8.2/missing: 81: /home/sheldon/work/linux_project/gdb-8.2/missing: makeinfo: not found WARNING: ‘makeinfo‘ is missing on your system. You should only need it if you modified a ‘.texi‘ file, or any other file indirectly affecting the aspect of the manual. You might want to install the Texinfo package: <http://www.gnu.org/software/texinfo/> The spurious makeinfo call might also be the consequence of using a buggy ‘make‘ (AIX, DU, IRIX), in which case you might want to install GNU make: <http://www.gnu.org/software/make/> make[5]: *** [gdb.info] 错误 127 make[5]: 离开目录“/home/sheldon/work/linux_project/gdb-8.2/gdb/doc” make[4]: *** [subdir_do] 错误 1 make[4]: 离开目录“/home/sheldon/work/linux_project/gdb-8.2/gdb” make[3]: *** [install-only] 错误 2 make[3]: 离开目录“/home/sheldon/work/linux_project/gdb-8.2/gdb” make[2]: *** [install] 错误 2 make[2]: 离开目录“/home/sheldon/work/linux_project/gdb-8.2/gdb” make[1]: *** [install-gdb] 错误 2 make[1]: 离开目录“/home/sheldon/work/linux_project/gdb-8.2” make: *** [install] 错误 2 [email protected]-vm:~/work/linux_pro
解决方法:sudo apt-get install texinfo (或者从GNU下载源码自行编译安装:http://ftp.gnu.org/gnu/texinfo/)
--------②编译gdbserver(在Linux开发板上作为父进程运行,启动加了gdb调试信息的应用程序)
cd gdb/gdbserver/ //继续进入到gdbserver目录 ./configure --host=arm-linux //配置要运行的平台为arm-Linux开发板 make
make install prefix=../../tmp/gdbserver //指定安装到之前的tmp目录下
将编译生成的gdbserver通过nfs或usb复制到开发板上,后面就可以开始远程gdb调试了!
以上是关于GDB调试的学习的主要内容,如果未能解决你的问题,请参考以下文章