代码改变世界

GDB 调试

2024-04-11 21:49  清晨、午后  阅读(53)  评论(0编辑  收藏  举报

gdb的前提条件: g++ 或者 gcc 时,必须是带gdb参数的 ,如 cmake 中 SET(CMAKE_CXX_FLAGS_DEBUG   " $ENV{CXXFLAGS} -O0 -Wall -g ")

1.启动

gdb ./软件名称

对于已经运行的程序

gdb attach $(pidof 进程名 如 tmsserver )

gdb -p ` pidof tmsserver `
关闭进程
killall $(pidof ag)

2.GDB设断点 

当前文件中

(gdb) b func-name
(gdb) b line-num

注意有的函数需要带类名、命名空间 ,如

(gdb) b std::cMMM::Proc

其他文件中

(gdb) break <file-name>: <func-name>
(gdb) break <file-name>: <line-num>

查看断点

info break  

删除断点

delete num
delete // 删除所有断点

3.查看、监视

一直显示变量的值
display {ulMP_PreAlarmProc}

监视变量g,当变量的值发送改变时给出显示
watch g
Old value = 6
New value = 7

设置输出格式,
(gdb) set print pretty //这种打印比较好看

打印变量
(gdb)set print element 0    //设置显示任意长度

打印一定长度字节的内容
(gdb) p *data@52

16进制格式打印(网络调试助手可以转换16进制到字符,man ascll)
(gdb) p /x *data@52


打印内存
dump binary memory /home/1001  起始地址 终止地址

4.运行

r  // 重新运行
n  //单步运行
u LineNum      //跳到指定行
c // 继续运行
step //跳入函数 简写 s
finish //跳出函数,函数完整执行后返回
return // 直接返回, 跳过当前函数后面的语句直接返回,返回值可以自定义,紧跟在return命令后面即可

5.多线程调试锁定开启

show scheduler-locking       //线程调试 显示线程状态
set scheduler-locking on     //调试加锁当前线程,其他线程停止
set scheduler-locking off    //启动线程

6.调试 .so 文件

1、gdb server  // 首先启动gdb

2、b main  // 先任意打断点,确保在目标断点前可停下

3、r  // 运行程序,目的是加载动态库

4、directory /opt/DZWDSJ/VRV/lib/vrvlib/      // 该目录为  .so 的存放目录

4、对产生 .so 文件的函数或文件行数均可设置断点(即最初想调试的目标断点

99.其他基本指令:

(大部分命令使用时只要输入第一个字母就好了,同时支持TAB的自动补全,与shell相类似)

99.1. 查看栈信息(bt frame up down ) 

当程序被停住了,你需要做的第一件事就是查看程序是在哪里停住的。当你的程序调用了一个函数,函数的地址,函数参数,函数内的局部变量都会被压入“栈”(Stack)中。你可以用GDB命令来查看当前的栈中的信息。  下面是一些查看函数调用栈信息的GDB命令:    

bt: 打印当前的函数调用栈的所有信息。如:
(gdb) bt #0 func (n=250) at tst.c:6 #1 0x08048524 in main (argc=1, argv=0xbffff674) at tst.c:30
#2 0x400409ed in __libc_start_main () from /lib/libc.so.6 从上可以看出函数的调用栈信息:__libc_start_main --> main() --> func() bt <n>: n是一个正整数,表示只打印栈顶上n层的栈信息。 bt <-n>:-n表一个负整数,表示只打印栈底下n层的栈信息。
如果你要查看某一层的信息,你需要在切换当前的栈,一般来说,程序停止时,最顶层的栈就是当前栈,如果你要查看栈下面层的详细信息,首先要做的是切换当前栈。 f
<n> : n是一个从0开始的整数,是栈中的层编号。比如:frame 0,表示栈顶,frame 1,表示栈的第二层。

99.2查看当前栈层的信息,可以用以下GDB命令:     

  frame 或 f :会打印出这些信息,栈的层编号,当前的函数名,函数参数值,函数所在文件及行号,函数执行到的语句。    

  info f :这个命令会打印出更为详细的当前栈层的信息,只不过,大多数都是运行时的内内地址。比如:函数地址,调用函数的地址,被调用函数的地址,目前的函数是由什么样的程序语言写成的、函数参数地址及值、局部变量的地址等等。如:     

  info args:打印出当前函数的参数名及其值。     

  info locals:打印出当前函数中所有局部变量及其值。     info catch:打印出当前的函数中的异常处理信息。