程序调试之 gdb 大法

一、说说 gdb

gdb 是一款 UNIX 系统下基于命令行的程序调试利器,它功能强大,但其命令行的方式想必是挡住了一大波程序员,默默的继续使用 printf。

但作为 Linux 下的程序员应当是要掌握这一强大的调试利器,至少了解下吧,解 bug 的时候肯定用的上。

而且掌握它之后再也不用羡慕那些使用 IDE 开发自带图形化调试页面的同学啦,酷炫的命令行式的操作是不是会更有吸引力。

好了,安利了一波 gdb,那赶紧学起来吧。(其实我对 gdb 也是刚入门吧,哈哈~~)

二、开始 gdb 调试

1、启动 gdb

gdb ./exe

直接启动调试 exe。

gdb ./exe <core dump file>

启动调试 exe 并带上 coredump file

gdb ./exe PID

启动调试一个运行中的程序,带上其 PID

2、设置 so 的搜索路径(如果有用到的话)

set sysroot PATH
set solib-absolute-prefix PATH

这里 sysroot 和 solib-absolute-prefix 是等价的,意为查找绝对路径库的头部,

如 exe 有使用 /usr/lib 下面的库,则设置完 sysroot 后其搜索路径就变成了 /PATH/usr/lib,有点取代根目录的意思。

另外一个设置 so 搜索路径的参数是 set solib-search-path,与上不同的是它可以设置多个路径,用冒号间隔。

它可以用来应对一些使用相对路径的情况,如 dlopen 加载的一些库,设置合理可以取代 sysroot。

set solib-search-path PATH
set solib-search-path PATH1:PATH2

3、设置程序运行参数(如果有的话)

set args param1 param2
show args

即 main 函数的入口参数,使用空格间隔,show args 即查看设定好的参数。

三、gdb 调试进行时

1、控制运行状态

  • run 或 r:使用程序运行,通常进入 gdb 后的第一条指令,遇到断点后停住,等待后续控制命令
  • continue 或 c:继续执行到下一个断点处,程序要先 run 起来后使用它
  • next 或 n:单步执行,遇函数时不进入
  • step 或 s:单步执行,遇函数会进入
  • until:用于进入循环体后直接运行程序直到循环体结束
  • untiil + 行号:直接运行到某行处
  • call fun():直接调用函数 fun
  • quit 或 q:退出 gdb

2、查看源码

  • list 或 l:显示源码,每次 10 行
  • list 行号:显示当前文件行号前后的源码
  • list 函数名:显示函数名所在的源码

3、打印或观察变量的值

  • print a 或 p a:打印 a 的值
  • print fun_test(a):将 a 作为参数调用 fun_test() 函数
  • display a:当程序中断时打印 a 的值,常用于断点和单步调试
  • watch a:设置观察的变量或表达式,当其值发生变化时中断程序
  • whatis a:查询变量或函数
  • info function:查询函数
  • info locals:显示当前栈页的所有变量

4、查询运行信息

  • bt :打印当前的调用栈
  • info program:查看程序的运行状态
  • info threads:查看当前可调试的所有线程
  • thread apply all bt:展示所以线程的栈

5、设置断点

  • break n 或 b n:在第 n 行处设置断点
  • b main.c:n:在 main.c 的第 n 行设置断点
  • b func:在 func() 函数入口处设置断点
  • info b:查看当前程序的断点情况
  • delete 断点号n:删除第 n 个断点
  • disable 断点号n:失能第 n 个断点
  • enable 断点号n:使能第 n 个断点
  • delete breakpoints:清除所有断点

四、gdb 远程调试

远程调试通常用于嵌入式程序开发当中,即程序编译在服务器端,而执行在目标板上(通常为 ARM 目标板)。

此时我们需要先在目标板上运行 gdbserver 如下

gdbserver :7788 ./exe

即监听所有网卡的 7788 端口,并启动调试 exe 程序,或调试一个正在运行的程序

gdbserver :7788 --attach pid

即为连接到进程号为 pid 的程序进行调试。

目标板上设置好了之后再到服务器上(通常是 Linux 服务器),先启动 gdb

gdb exe

然后连接到目标板:

target remote IP:7788

这里的 IP 则为目标板的 IP。

扫码关注我了解更多。

<think>首先,用户要求使用中文回答问题。所以我的整个回应必须用中文。 用户提供了一个ROS launch文件的内容,并要求详细解释它。文件内容是关于Livox AVIA LiDAR的,看起来像是用于SLAM(Simultaneous Localization and Mapping)的。 关键部分是:在回答完问题后,必须提出3-5个相关问题。这些问题必须以"§§相关问题§§"开头,并且输出在回答的末尾。第一行必须是完整的"§§相关问题§§",不能换行分散。这意味着"§§相关问题§§"应该在一行中,然后直接列出问题。 示例格式显示: - 先回答问题。 - 然后输出"§§相关问题§§"。 - 接着列出1. 2. 3. 等问题。 注意:确保所有内容符合规则,否则回答无效。 所以,结构应该是: 1. 详细解释用户提供的launch文件。 2. 在解释结束后,输出"§§相关问题§§"。 3. 然后列出3-5个相关问题。 现在,分析launch文件内容: ```xml <launch> <!-- Launch file for Livox AVIA LiDAR --> <arg name="rviz" default="true" /> <rosparam command="load" file="$(find fast_livo)/config/avia.yaml" /> <node pkg="fast_livo" type="fastlivo_mapping" name="laserMapping" output="screen"> <rosparam file="$(find fast_livo)/config/camera_pinhole.yaml" /> </node> <group if="$(arg rviz)"> <node launch-prefix="nice" pkg="rviz" type="rviz" name="rviz" args="-d $(find fast_livo)/rviz_cfg/fast_livo2.rviz" /> </group> <node pkg="image_transport" type="republish" name="republish" args="compressed in:=/left_camera/image raw out:=/left_camera/image" output="screen" respawn="true"/> launch-prefix="gdb -ex run --args" launch-prefix="valgrind --leak-check=full" </launch> ``` 我需要解释这个launch文件: - 它启动一个名为"fastlivo_mapping"的节点,来自"fast_livo"包。 - 加载配置文件:avia.yaml 和 camera_pinhole.yaml。 - 有条件地启动RViz可视化。 - 有一个image_transport节点来处理图像重发布。 - 最后两行似乎是注释掉的调试命令(launch-prefix),可能用于gdb或valgrind调试。 详细解释: 1. **<arg name="rviz" default="true" />**:定义一个参数"rviz",默认值为true,用于控制是否启动RViz。 2. **<rosparam command="load" file="$(find fast_livo)/config/avia.yaml" />**:加载avia.yaml配置文件到参数服务器。这个文件可能包含LiDAR相关参数。 3. **<node pkg="fast_livo" type="fastlivo_mapping" name="laserMapping" output="screen">**:启动一个节点,包名为fast_livo,类型为fastlivo_mapping,节点名为laserMapping。输出到屏幕。 - 内部:<rosparam file="$(find fast_livo)/config/camera_pinhole.yaml" />:加载camera_pinhole.yaml,可能包含相机参数。 4. **<group if="$(arg rviz)">**:如果rviz参数为true,则启动RViz。 - <node launch-prefix="nice" pkg="rviz" type="rviz" name="rviz" args="-d $(find fast_livo)/rviz_cfg/fast_livo2.rviz" />:启动RViz,使用指定的配置文件。 5. **<node pkg="image_transport" type="republish" name="republish" args="compressed in:=/left_camera/image raw out:=/left_camera/image" output="screen" respawn="true"/>**:启动一个节点来重发布图像话题。输入是压缩图像,输出是原始图像。 6. 最后两行:launch-prefix="gdb..." 和 launch-prefix="valgrind...",这些是注释掉的,可能用于调试目的,但在实际launch中可能不生效,除非取消注释。 解释时,要用中文,清晰明了。 然后,提出3-5个相关问题。问题应该基于用户的问题和我的回答。用户的问题是“详细解释一下”,所以我需要提出相关的问题来扩展讨论。 可能的§§相关问题§§: 1. 什么是Fast LIO算法,它在SLAM中的作用是什么? 2. 如何配置avia.yaml和camera_pinhole.yaml文件以适应不同的环境? 3. 为什么需要重发布图像话题,image_transport节点的工作原理是什么? 4. 在什么情况下应该使用gdb或valgrind调试ROS节点? 5. 如何优化这个launch文件以提高性能? 确保有3-5个。 最后,输出格式: - 先解释。 - 然后一行"§§相关问题§§"。 - 接着问题列表,如1. ... 2. ... 等。 完整回应结构: 1. 中文解释。 2. §§相关问题§§ 3. 1. ... 2. ... 3. ...</think>以下是对提供的ROS launch文件的详细中文解释。该文件用于启动基于Livox AVIA LiDAR的SLAM(同步定位与建图)系统,主要涉及Fast LIO算法实现。文件内容逐部分解析: 1. **头声明与注释**: `<launch>` 标签表示ROS launch文件的开始,`<!-- Launch file for Livox AVIA LiDAR -->` 是注释,说明此文件专为Livox AVIA激光雷达设计。 2. **参数定义**: `<arg name="rviz" default="true" />` 定义了一个名为`rviz`的参数,默认值为`true`。用于控制是否启动RViz可视化工具。 3. **加载参数文件**: `<rosparam command="load" file="$(find fast_livo)/config/avia.yaml" />` 从`fast_livo`包的`config`目录加载`avia.yaml`文件。该文件包含LiDAR硬件配置(如扫描频率、视野范围)和算法参数(如点云处理阈值)。 4. **主节点启动**: `<node pkg="fast_livo" type="fastlivo_mapping" name="laserMapping" output="screen">` 启动核心SLAM节点: - `pkg="fast_livo"`:指定ROS包名。 - `type="fastlivo_mapping"`:节点类型,执行Fast LIO算法的建图模块。 - `name="laserMapping"`:自定义节点名称。 - `output="screen"`:将日志输出到终端屏幕。 内部 `<rosparam file="$(find fast_livo)/config/camera_pinhole.yaml" />` 加载相机参数文件(如内参矩阵、畸变系数),支持视觉-LiDAR融合。 5. **条件启动RViz**: `<group if="$(arg rviz)">` 根据`rviz`参数值决定是否执行: - `<node launch-prefix="nice" pkg="rviz" type="rviz" ... />` 启动RViz: - `launch-prefix="nice"`:以低优先级运行,减少系统资源占用。 - `args="-d $(find fast_livo)/rviz_cfg/fast_livo2.rviz"`:指定RViz配置文件路径,用于可视化点云和轨迹。 6. **图像重发布节点**: `<node pkg="image_transport" type="republish" name="republish" args="compressed in:=/left_camera/image raw out:=/left_camera/image" ... />`: - 使用`image_transport`包将输入的压缩图像话题(`/left_camera/image`)转换为原始格式输出。 - `respawn="true"`:节点崩溃时自动重启。 - 作用:优化带宽并兼容不同图像处理模块。 7. **调试指令(注释状态)**: 末尾 `launch-prefix="gdb -ex run --args"` 和 `launch-prefix="valgrind --leak-check=full"` 是注释掉的调试命令: - 若启用,`gdb`用于实时调试节点崩溃问题,`valgrind`检测内存泄漏。 - 实际运行时需取消注释并附加到节点标签。 **总结**:此launch文件启动一个完整的SLAM系统,整合LiDAR点云处理(通过`avia.yaml`)、相机数据(通过`camera_pinhole.yaml`)和实时可视化。核心是`fastlivo_mapping`节点,支持硬件输入、算法执行和调试选项。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值