在开发定位过程中,肯定会用到gdb去跟踪定位分析问题,下面是记录一些常用的命令,方便后续查找。
1:比如我要自己编译一个小程序,然后想用gdb去跟踪,
在GDB下调试一个小程序的基本步骤如下:
1.编写源代码:
// hello.c
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
-
2.编译源代码,生成可执行文件:想要能用gdb跟进去调试,就需要加上-g
gcc -g hello.c -o hello
如果里面有创建线程的,编译的时候需要加上-lpthread,如下:
gcc -g hello.c -o hello -lpthread
3.使用GDB调试程序:
gdb hello
4.在GDB环境中进行调试,例如设置断点、查看变量值等:
(gdb) break main # 设置断点在main函数处
(gdb) run # 运行程序
(gdb) print i # 查看变量i的值(如果程序中有int i;)
(gdb) quit # 退出GDB以上步骤可以帮助你使用GDB对一个简单的程序进行调试。
5.调试core文件
Core Dump:Core的意思是内存,Dump的意思是扔出来,堆出来(段错误)。开发和使用Unix程序时,有时程序莫名其妙的down了,却没有任何的提示(有时候会提示core dumped),这时候可以查看一下有没有形如core.进程号的文件生成,这个文件便是操作系统把程序down掉时的内存内容扔出来生成的, 它可以做为调试程序的参考,能够很大程序帮助我们定位问题。那怎么生成Core文件呢?
生成Core方法
产生coredump的条件,首先需要确认当前会话的ulimit –c,若为0,则不会产生对应的coredump,需要进行修改和设置。
即便程序core dump了也不会有core文件留下。我们需要让core文件能够产生,设置core大小为无限:ulimit -c unlimited
更改core dump生成路径
因为core dump默认会生成在程序的工作目录,但是有些程序存在切换目录的情况,导致core dump生成的路径没有规律,
所以最好是自己建立一个文件夹,存放生成的core文件。
我建立一个 /data/coredump 文件夹,在根目录data里的coredump文件夹。
————————————————
调用如下命令:echo /data/coredump/core.%e.%p> /proc/sys/kernel/core_pattern
将更改core文件生成路径,自动放在这个/data/coredump文件夹里。
%e表示程序名, %p表示进程id
6、关于断点
可以使用
b
+文件名+行号,或者指定函数名,可用if
限定条件断点。
使用info breakpoints
列出所有断点,使用delete 1
删除编号为1的断点。break test.c:6
break test.c:6 if num>0
b fucntionname
6、关于源代码查看
list first,last
list 6, 20
显示代码6-20行
7:关于调试多线程程序
查看当前运行的进程
ps -aux | grep main查看当前运行的轻量级进程
ps -aL | grep -w main查看主线程和新线程的关系
pstree -p 主线程id
8:gdb进去怎么打印地址内容
gdb调试时可以使用以下方式打印变量,
- x
- whatis
- ptype
- info
命令 作用 x/s str 打印字符串str set print elements 0 打印不限制字符串长度/或不限制数组长度 call printf("%s\n", xxx) 这是打印出的字符串不会含有多余的转义字、符 printf("%s\n", xxx) 打印指针/结构体
命令 作用 print ptr 查看该指针指向的类型及指针地址 print *(struct xxx *)ptr 查看指向的结构体内容 打印数组
命令 作用 print *array@10 打印从数组开头连续10个元素的值 print array[60]@10 打印第60~69个元素 set print array-indexes on 打印数组元素时,同时打印数组下标 *(float *)(addr)@num 打印地址值 将addr转换成float*类型,并打印num个值 打印指定内存地址的值
使用x命令来打印内存的值,格式为x/nfu addr,以f格式打印从addr开始的n个长度单元为u的内存值。
- n:输出单元的个数
- f : 输出格式,如x表示以16进制输出,o表示以8进制数处,默认x
- u:一个单元的长度,b表示1byte,h表示2byte(half word),w表示4byte,g表示8byte(giant word)。
命令 作用 x/8xb 16进制形式打印8byte x/8xw 16进制形式打印8个单字(word) x/10sg 字符串形式打印10个双字 上面这个命令还是比较好用的,直接在gdb里面打印:
x/32xg
(gdb) info line demo_lock.c:13
Line 13 of "demo_lock.c" starts at address 0xaaaaaaaa0a08 <process+44> and ends at 0xaaaaaaaa0a14(gdb) x/32xg 0xaaaaaaaa0a08
0xaaaaaaaa0a08 <process+44>: 0x91006000d0000080 0xb000008097ffffa4.................................................................................................................................
就这样连续的打
link:
https://blog.csdn.net/weixin_68063596/article/details/132342865 ---- 这个里面介绍的比较全面
https://zhuanlan.zhihu.com/p/508160353 -----gdb进去,打印地址内容