2023-08-09 GDB调试ros2程序

-g内s存泄露查看工具:perf
参考:

  1. GDB使用详解

一、ROS2程序

编译要求

  1. 要使用GDB调试某个程序,编译时需要加上-g编译选项: add_compile_options(-g),或者set(CMAKE_<LANG>_FLAGS "${CMAKE_CXX_FLAGS} -g")

启动方法

  1. 不使用ros2 run的指令启动节点,而是进入节点可执行程序所在目录(install/里面),在控制台输入$ ./app
  2. GDB调试启动:进入可执行程序所在目录,在控制台输入$ gdb ./app

二、GDB调试指令

在控制台以gdb启动程序后通过指令控制程序执行,然后通过指令控制调试。

常用指令

gdb常用指令.png

指令用法

gdb ./filename方式启动GDB调试只是附加一个调试文件,并没有启动这个程序,需要输入指令来控制程序的启动和执行。

  1. run: 启动程序,在GDB界面按Ctrl + C让GDB中断,再次输入r,GDB会询问是否重启程序,输入yyes
  2. continue: 当GDB触发断点或者Ctrl + C中断后,输入c即可
  3. break: 简写b,用于添加断点,方式如下
  • break FunctionName: 在函数的入口处添加一个断点
  • break LineNo: 在当前文件行号为LineNo处添加一个断点
  • break FileName:LineNo: 在FileName文件行号LineNo处添加一个断点
  • break FileName:FunctionName: 在FileName文件FunctionName函数的入口处添加断点
  • break -/+offset: 在当前程序暂停位置的前/后offset行处下断点
  • break...if cond: 下条件断点
  1. 断点管理指令
  • info breaki b: 显示当前所有断点信息
  • disable 断点编号: 禁用断点
  • enable 断点编号: 启用断点
  • delete 断点编号: 删除断点
  1. 查看堆栈
  • backtrace或者bt: 查看当前调用堆栈
  • frame 堆栈编号或者f 堆栈编号: 切换到其他堆栈处
  1. list: 输出上一次list命令显示的代码后面的代码,第一次则显示当前位置附近代码
  • list -: 显示上一次list显示的前面的代码
  • list LineNo: 显示当前文件LineNo行附近代码
  • list FileName:LineNo: 显示FileName文件第LineNo行附近的代码
  • list FunctionName: 显示当前文件FunctionName函数附近的代码
  • list FileName:FunctionName: 显示FileName文件FunctionName函数附近的代码
  • list from,to: 其中from和to是代码位置,显示这之间代码
  • show listsize: 查看list显示的代码行数
  • set listsize count: 设置list显示的代码行数为count
  1. print和 type`: 查看变量
  • print param: 在调试过程中查看变量的值
  • print param=value: 在调试过程中修改变量的值
  • print a+b+c: 可以进行一定的表达式计算,这里是计算a、b、c三个变量之和
  • print func(): 输出func函数执行的结果,常见的用途是打印系统函数执行失败原因:print strerror(errno)
  • print *this: 在c++对象中,可以输出当前对象的各成员变量的值
  1. whatisptype: 查看变量类型
  • whatis val: 用于查看变量类型
  • ptype val: 可以查看复合数据类型,打印出该类型的成员变量
  1. thread: 命令
  • info thread: 查看当前进程的所有线程运行情况
  • thread 线程编号: 切换到具体编号的线程上去
  1. nextstep: 单步调试
  • next: 单步步过(step over),即遇到函数直接跳过,不进入函数内部
  • step: 单步步入(step into),即遇到函数会进入函数内部
  1. returnfinish: 退出函数命令
  • return: 立即退出当前函数,剩下的代码不会执行了,return 还可以指定函数的返回值
  • finish: 会继续执行完该函数剩余代码再正常退出
  1. until: 与break命令类似
  2. jump
  • jump LineNo,跳转到代码的 LineNo 行的位置
  • jump +10,跳转到距离当前代码下10行的位置
  • jump *0x12345678,跳转到 0x12345678 地址的代码处,地址前要加星号
  • 中间跳过的代码是不会执行的
  • 跳到的位置后如果没有断点,那么GDB会自动继续往后执行
  1. disassemble: 查看某段代码的汇编指令
  2. set argsshow args: 设置程序启动参数
  • 很多程序启动需要我们传递参数,set args 就是用来设置程序启动参数的,show args 命令用来查询通过 set args 设置的参数
  • set args args1: 设置单个启动参数 args1
  • set args "-p" "password",如果单个参数之间有空格,可以使用引号将参数包裹起来
  • set args args1 args2 args3,设置多个启动参数,参数之间用空格隔开
  • set args,不带参数,则清除之前设置的参数
  1. tbreak: 添加一个临时断点,断点一旦被触发就自动删除,使用方法同 break
  2. watch: 命令用来监视一个变量或者一段内存,当这个变量或者内存的值发生变化时,GDB就会中断下来。被监视的某个变量或内存地址会产生一个 watch point(观察点)
  • watch 整型变量
  • watch 指针变量,监视的是指针变量本身
  • watch *指针变量,监视的是指针所指的内容
  • watch 数组变量或内存区间
  • 当 watch 的变量或内存因超出作用域失效时,GDB 会有提示信息
  • 通过 info watch 命令可以查看当前所有监视的变量,通过 delete watch编号 可以删除对某个变量的监视
  1. call: 执行指定函数
  • call func(): 执行 func() 函数,同 print func()
  1. help: 查看目标命令的具体用法

三、GDB多线程调试

用GDB调试多线程程序时,该程序的编译需要添加 -lpthread 参数。

一些命令

  1. info thread: 查看当前调试程序启动了多少个线程,并打印出各个线程信息
  2. thread 线程编号: 将该编号的线程切换为当前线程
  3. thread apply 线程编号1 线程编号2 ... command: 将GDB命令作用指定对应编号的线程,可以指定多个线程,若要指定所有线程,用 all 替换线程编号
  4. break location thread 线程编号: 在 location 位置设置普通断点,该断点只作用在特定编号的线程上

一些术语

  1. all-stop mode: 全停模式,当程序由于任何原因在GDB下停止时,不止当前的线程停止,所有的执行线程都停止。这样允许你检查程序的整体状态,包括线程切换,不用担心当下会有什么改变
  2. non-stop mode: 不停模式,调试器(如VS2008和老版本的GDB)往往只支持 all-stop 模式,但在某些场景中,我们可能需要调试个别的线程,并且不想在调试过程中影响其他线程的运行,这样可以把GDB的调式模式由 all-stop 改成 non-stop,7.0 版本的GDB引入了 non-stop 模式。在 non-stop 模式下 continue、next、step 命令只针对当前线程
  3. record mode: 记录模式
  4. replay mode: 回放模式
  5. scheduler-locking: 调度锁
  6. schedule-multiple: 多进程调度

设置线程锁

使用GDB调试多线程程序时,默认的调试模式是:一个线程暂停运行,其他线程也随即暂停;一个线程启动运行,其他线程也随即启动。但在一些场景中,我们希望只让特定线程运行,其他线程都维持在暂停状态,即要防止线程切换,要达到这种效果,需要借助 set scheduler-locking 命令。

  • set scheduler-locking on,锁定线程,只有当前或指定线程可以运行
  • set scheduler-locking off,不锁定线程,会有线程切换
  • set scheduler-locking step,当单步执行某一线程时,其他线程不会执行,同时保证在调试过程中当前线程不会发生改变。但如果在该模式下执行 continue、until、finish 命令,则其他线程也会执行
  • show scheduler-locking,查看线程锁定状态
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容