受限情况下的程序调试

说明

  • 嵌入式开发中,有些情况无法使用gdb调试,例如:
  1. 平台不支持,例如:之前使用一款RK的芯片,芯片原厂告知不支持gdb调试,原厂未移植成功。
  2. 资源受限,例如:低端产品资源不足或者缺失关键资源(内存,存储空间或者CPU性能不足,物理接口只有串口等),导致gdb无法运行。
  3. 特殊时期,产品无法使用gdb调试,例如:测试,生产,售后时期都无法再通过gdb调试。
  • 在C/C++开发中,gdb的使用对于程序崩溃问题定位有很大帮助;无法使用gdb,能够获取到的有效的信息非常少,定位偶发性的崩溃问题无异于大海捞针,因此我们需要其它调试手段。

调试方式

定位问题需要的调试信息

  • 不管是通过gdb调试还是其它方式,定位问题都需要一些关键信息,如下:
  1. 出问题的代码行和变量值。
  2. 出问题时的函数调用栈。

支持gdb,其它因素导致不能使用gdb的情况

  • gdb调试非常方便和能够帮助我们快速定位问题,因此在这种情况下,我们应该尽可能的创建条件来使用gdb。
  • 使用gdb调试需要更改编译配置,会增大程序和库的文件大小。

gdbserver

  • 有些平台可能运行不了gdb,但是可以试下gdbserver,大部分嵌入式平台都推荐使用gdbserver的方式而不是直接运行gdb。
  • 前提是:设备需要支持网络。
  • 使用方式略。

coredump

  • coredump是程序崩溃后Linux内核将调试信息保存为存储空间的文件,用户可以在其它平台通过coredump文件对程序进行分析。
  • 前提是:
  1. coredump支持程序崩溃情况。
  2. coredump文件需要占用一定存储空间,文件大小可能会比较大。
  • 使用方式略。

coredump + 优化使用方式

  • 使用coredump可能会存在两个问题,如下:
  1. 采用-g编译的程序和库,文件大小可能大大增加。
  2. 生成的coredump文件较大,设备存储不了
  • 减小文件大小,可以使用strip后的Debug版本的程序进行问题复现,再使用未strip的Debug版本的程序进行coredump调试,strip版本只是去掉了调试信息和符号表,但是两个程序代码段,函数地址等都没有变化,strip程序奔溃后的coredump信息能够在未strip的程序调试使用。
  • 文件存储,可以采用tmpfs(内存文件系统),将文件放在内存中,或者NFS(网络文件系统),设备起来后连上网络,自动mount远程目录,将coredump文件存储到远程目录中,甚至设备中不存储测试程序直接运行远程的程序。

无法使用gdb的情况

  • 大部分无法使用gdb的情况,其它复杂的调试工具也是无法使用的,通常只能依靠代码的方式来帮助调试,例如:调试打印,日志等。

定位出问题的代码行和参数值

  • C/C++编程中,常见的崩溃问题很大概率是指针问题,如果没有使用任何调试手段,出问题后没有任何信息,很难定位是哪行代码导致的,就像大海捞针一样。
指针问题
  • 常见的处理方式是:对每个指针操作,先判断指针是否为NULL;
  • 缺陷:判空操作虽然可以避免程序崩溃,但是也会掩盖问题,例如:预期指针是不可能为空,但是指针出现为空了,加上判空处理后,程序执行分支不符合预期,程序未崩溃,并且可能没产生明显现象,导致问题被掩盖。
  • 正确做法:使用断言可以处理该问题,如果指针预期不为空,则加上断言判断,当问题出现,程序崩溃后,会打印出崩溃的代码行;如果指针预期可能为空,则使用if判断并加上打印,打印执行分支。
QT中使用:Q_CHECK_PTR(m_Loading);

Launcher: UserInterface/MainWidget/WarningWidget/Phone_PopupWidget.cpp:119: void Phone_PopupWidget::hidePopup(): Assertion `m_Loading' failed.
  • 崩溃问题可以使用backtrace来定位,使用方式
  • 普通问题只能通过log和打印调试信息来定位,因此在debug阶段log信息越丰富越详细越好。

获取函数调用栈

  • 只知道出问题的代码行,不清楚函数的调用关系,也无法确定问题。
  • 如果程序崩溃可以通过backtrace来打印函数调用栈;普通问题只能通过log和调试信息来确定函数调用栈,debug模式下,每个函数在函数入口处打印函数名等信息,这样就可以实现打印函数调用栈。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值