麒麟系统开发笔记(十一):在国产麒麟系统上使用gdb定位崩溃异常方法流程进阶定位代码行数及专项测试Demo

前言

  上一篇,通过研究,可以定位到函数,本篇进一步优化,没有行数,程序较为复杂的时候,就无法定位,所以进一步定位。
  本篇做了 qBreakpad 的研究,但是没有成功,过程也还是填出来,后来突然注意到 gdb 出现行数的方法,并通过了几轮测试以及实战,确实可以定位到行数,所以为了大家方便,把国企麒麟上的 Qt 崩溃方法分享出来。
  本篇文章比较长,就不分篇了,同时还做了专项测试。

 

注意

  阅读者如果一开始有点懵,可能先要看先大致扫一下:《麒麟系统开发笔记(十):在国产麒麟系统上使用 gdb 定位崩溃异常方法流程以及测试 Demo》,本篇也是解决上一篇探讨的遗留问题(只定位了函数,未定位代码行号)。

 

使用 gdb 定位 Qt 的 release(国产麒麟系统)

步骤一:修改上一篇 demo 的 pro 配置

  (这里是上一篇的 demo,只关注红框的即可)
  在这里插入图片描述

步骤二:重新编译调试还是没有行号

   在这里插入图片描述

  在这里插入图片描述

  在这里插入图片描述

  与没有 -g 的时候没有啥区别。

步骤三:多加几层调用追加堆栈测试

  修改下代码:
  在这里插入图片描述

  在这里插入图片描述

  测试:
  在这里插入图片描述

  还是没有堆栈信息:
  在这里插入图片描述

步骤四:怀疑是 release 版本,改为 debug 测试

  改为 debug 版本,也没有:
  在这里插入图片描述

  不清楚原因,这里博主就没有深究了

步骤五:路回峰转,重启 gdb,成功定位

  研究 qBreakpad 去了,但是 qBreakpad 也入深坑了,在爬坑的时候,突然注意到 gdb 的 bt 指令,所以研究了个把小时 qBreakpad 又折回来继续了。
  在这里插入图片描述
  至此,出现了行号:
  在这里插入图片描述

 

配置调试发布专项测试

  为了确认最简单的方式,所以进行测试:

DEFINES += QT_NO_DEBUG_OUTPUT
DEFINES += QT_NO_WARN_OUTPUT
QMAKE_CXXFLAGS += -g 
#QMAKE_CXXFLAGS += -g3

测试:debug 版本,无 -g,不屏蔽 qt 打印输出

  在这里插入图片描述

测试:debug 版本,有 -g 的,不屏蔽 qt 打印输出

  在这里插入图片描述

  有行号,行号跟函数在同一行。

测试:debug 版本,有 -g 的,屏蔽 qt 打印输出

  在这里插入图片描述

  有行号,行号跟函数在同一行。

测试:release 版本,有 -g/-g3,有 qt 屏蔽打印输出

#DEFINES += QT_NO_DEBUG_OUTPUT
#DEFINES += QT_NO_WARN_OUTPUT
QMAKE_CXXFLAGS += -g 
#QMAKE_CXXFLAGS += -g3

  在这里插入图片描述

  在这里插入图片描述

  在这里插入图片描述

  还试了下 -g3:
  在这里插入图片描述

  定位了函数,不定位行号。

测试:release 版本,有 -g/-g3,未屏蔽 qt 打印输出

  在这里插入图片描述

  所以,最终发现是不能屏蔽 qt 打印输出的,不然是没有的,跟 release 或者 debug 没有关系(没有去论证 debug 下屏蔽 qt 打印输出了)

测试:release 版本,无 -g,未屏蔽 qt 打印输出

  在这里插入图片描述

  所以,无 -g 也不行

模拟实战

  先加了一句代码:
  在这里插入图片描述

  取消屏蔽 qt 打印,加上 -g:
  在这里插入图片描述

  使用 release 编译后,运行崩溃:
  在这里插入图片描述

  定位 coredump 文件:
  在这里插入图片描述

  然后使用 gdb 的方法:
  在这里插入图片描述
  这里得行是 qlist.h 的行号,不是我们代码的行号,所以下标错误估计就这样了。可以判断出,越界也是最后某个地方调用指针导致错误,所以越界当时是不会有问题,当越界在用越界调用的就把出错的指针调用出行数打出来。
  下面试试指针错误:
  在这里插入图片描述

 

专项测试结论

  在这里插入图片描述

 

入坑

入坑一:gdb 不出现行数

问题

  Gdb 调试不出现行数

原因

  • 原因 1:release 与 debug 问题
  • 原因 2:-g 问题
  • 原因 3:是否屏蔽 qt 打印问题
      1+2+3,导致情况多种,花了不少时间定位

解决

  进行了专项测试论证,查看“专项测试论证”。

 

qBreakpad(此方法未通,贴出来参考,有兴趣的读者可以继续往下走)

  qBreakpad 下载地址:https://github.com/buzzySmile/qBreakpad

git clone --recursive https://github.com/buzzySmile/qBreakpad.git

  好像下下来有点问题,最后还是手动下载 zip 包了:
  在这里插入图片描述

  qBreakpad 依赖 breakpad 和 lss
   在这里插入图片描述

  下不下来,另外找把

  breakpad 下载地址:https://github.com/google/breakpad

  (最新版报错),下载 v2021.08.09 版本

  在这里插入图片描述

  lss:https://github.com/ithaibo/linux-syscall-support
  下载来:在这里插入图片描述

 

编译 qBreakpad 库

步骤一:下载解压

  在这里插入图片描述

步骤二:复制改名依赖库

  复制过去并改名:
  在这里插入图片描述

  改完后(先删除已经存在的):
  在这里插入图片描述

步骤三:使用 qtcreator 打开 qBreakpad 编译

  在这里插入图片描述

步骤四:解决错误“undefined reference to `google_breakpad::PEFile::TryGetDebugInfo(xxxx”,继续编译

  怀疑是版本问题,降低版本试试:
  在这里插入图片描述

  如下,下载解压后替换:
  在这里插入图片描述

步骤五:解决错误“*** No rule to make target ‘xxx/minidump_file_writer.cc’, needed by ‘_build/obj/minidump_file_writer.o’. Stop.”

  “*** No rule to make target ‘…/…/qBreakpad-master/third_party/breakpad/src/client/minidump_file_writer.cc’, needed by ‘_build/obj/minidump_file_writer.o’. Stop.”
  
  那岂不是要降低 qBreakpad 的版本?试一试
  至此,突然发现 gdb 的 bt,所以这边停止了。