OpenHarmony标准系统实践之GDB调试 原创 精华

深开鸿
发布于 2022-9-8 20:30
浏览
7收藏

作者:赵军霞

1.简介

OpenHarmony系统层代码大部分是C++ 实现的,运用了C++ 继承多态等特性,使得代码框架灵活,但是对于开发者代码走读,整理实现逻辑不太友好。利用GDB调试导出调用栈、查看中间变量状态,则能帮助开发者快速清晰化实现逻辑链,不仅提升代码走读效率,而且提高Issue定位效率。

2.实践过程

本文从以下几方面介绍使用GDB调试OpenHarmony源码的过程与案例:

  1. 如何制作OpenHarmony之GDB;

  2. 如何准备可调试动态库;

  3. 如何使用GDB调试动态库;

  4. 案例展示;

2.1 制作OpenHarmony之GDB

如果已经有配套版本的GDB程序了,可以跳过这节直接进入下一步:2.3.1 上传GDB,将GDB工具上传到目标开发板。另外,为了方便,以下所有命令都在ubuntu编译机的root用户下进行。

2.2.1准备arm-Linux交叉编译环境

  1. 新建目录

    新建目录,路径如下:

    /usr/local/ARM-toolchain/
    
  2. 获取工具包

    使用如下命令或者从浏览器手工下载arm-Linux交叉编译工具包

    wget https://releases.linaro.org/components/toolchain/binaries/latest-5/arm-linux-gnueabi/gcc-linaro-5.5.0-2017.10-x86_64_arm-linux-gnueabi.tar.xz
    
  3. 解压工具包

    将arm-Linux交叉编译工具包放在/usr/local/ARM-toolchain/目录下,使用以下命令解压:

    tar xvf gcc-linaro-5.5.0-2017.10-x86_64_arm-linux-gnueabi.tar.xz
    

    OpenHarmony标准系统实践之GDB调试-鸿蒙开发者社区

  4. 将该版本gcc的bin路径配置到系统环境变量PATH中,以便后续脚本执行能找到bin下的工具程序。

    export PATH=$PATH:/usr/local/ARM-toolchain/gcc-linaro-5.5.0-2017.10-x86_64_arm-linux-gnueabi/bin/
    

2.2.2下载、编译GDB源码包

示例使用的版本是gdb-8.2.1.tar.gz,在以下路径获取

https://mirrors.ustc.edu.cn/gnu/gdb/

在ubuntu编译机上任意建一个目录存放该包。如:

/home/kaihong/zzcgdb/gdb

解压

tar zxvf gdb-8.2.1.tar.gz

进入解压后的文件目录

cd gdb-8.2.1

在该目录下新建build目录,用于生成Makefile文件

mkdir build

进入build目录

cd build/

OpenHarmony标准系统实践之GDB调试-鸿蒙开发者社区

使用…/configure生成gcc编译的Makefile文件,命令如下:

CC="/usr/local/ARM-toolchain/gcc-linaro-5.5.0-2017.10-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-gcc" CXX="/usr/local/ARM-toolchain/gcc-linaro-5.5.0-2017.10-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-g++" ../configure LDFLAGS=-static --prefix=$HOME/glibc32-2.6 -target=arm-linux-gnueabi --host=arm-linux-gnueabi

说明:

  1. 这里我用CC=和CXX=强行指定了arm编译器路径,因环境上/usr/bin/目录下有x86的gcc和g++,它们在PATH中可能会被优先找到,这样编出来就不是arm版的GDB程序了。

  2. 必须要指定LDFLAGS=-static (静态链接),这样编译时会把需要的库都一起编译进来,编译的结果会稍大一些,但能保证包含了所有需要的库。如果不指定这个参数,默认为动态链接方式,编译的GDB文件放到目标板上运行时可能会因找不到所需的依赖库而无法启动。

  3. 这一步执行完成后,builld目录下就成功生成了MakeFile文件。

OpenHarmony标准系统实践之GDB调试-鸿蒙开发者社区

开始编译

make -j32
make install

两步都成功后,在build/gdb/目录下就生成了目标文件GDB
OpenHarmony标准系统实践之GDB调试-鸿蒙开发者社区

可通过file命令检查编处的是否确实是arm版的GDB
OpenHarmony标准系统实践之GDB调试-鸿蒙开发者社区

2.2 准备可调试动态库

开发板中将待调试的libnapitest.z.so动态库替换为携带调试信息的动态库

  1. 源码当中找到携带调试信息的动态库,命令如下:

     harmony@Ubuntu-64:~/OpenHarmony/out$ find ./ -name "*libnapites*" | xargs ls -lh
     -rwxrwxr-x 1 harmony harmony  47K 8月   5 09:29 ./rk3568-khdvk/innerkits/ohos-arm/napitest_interface/napitest/libnapitest.z.so
     -rwxrwxr-x 1 harmony harmony 766K 8月   5 09:28 ./rk3568-khdvk/lib.unstripped/napitest/napitest_interface/libnapitest.z.so
     -rwxrwxr-x 1 harmony harmony  47K 8月   5 09:28 ./rk3568-khdvk/napitest/napitest_interface/libnapitest.z.so
     -rw-rw-r-- 1 harmony harmony  10K 7月  29 18:07 ./rk3568-khdvk/packages/phone/NOTICE_FILES/system/lib/module/libnapitest.z.so.txt
     -rwxrwxr-x 1 harmony harmony  47K 8月   5 09:35 ./rk3568-khdvk/packages/phone/system/lib/module/libnapitest.z.so
    

    其中./rk3568-khdvk/lib.unstripped/napitest/napitest_interface/目录下的动态库(文件大小比其他文件大)为携带符号信息动态库,将该动态库下载到本地。

  2. 将携带符号信息的libnapitest.z.so动态库替换开发板中/system/lib/module目录下的libnapitest.z.so动态库。

    由于/system/lib/module目录下只有读写权限,无法直接将镜像上传到/system/lib/module目录下。因此可将镜像上传到data目录下,修改文件权限后,再将/system/lib/module目录下的libnapitest.z.so镜像替换为携带符号信息的镜像。具体操作命令如下:

     PS E:\hdc> .\hdc_std.exe file send .\libnapitest.z.so /data FileTransfer finish, Size:784348 time:134ms rate:5853.34kB/s PS 
     E:\hdc> .\hdc_std.exe shell 
     # mount -o remount,rw / 
     # cp /data/libnapitest.z.so /system/lib/module/
    

2.3 使用GDB调试动态库

2.3.1上传GDB

有了编译好的arm版GDB,把它上传到目标开发板。

这里我们以hdc_std工具上传为例,如果你有其他的文件传输方式也可以。

  1. 准备GDB和hdc_std工具

    在window主机上建一个目录,将ubuntu虚拟机上编译好的GDB拷贝过来,并拷贝一个hdc_std工具到该目录。
    OpenHarmony标准系统实践之GDB调试-鸿蒙开发者社区
    将开发板与window主机连接,确保hdc_std工具能够连接访问。

    在windows目录中开启第一个cmd命令行窗口,执行hdc_std shell 连接开发板。
    OpenHarmony标准系统实践之GDB调试-鸿蒙开发者社区

  2. 上传GDB程序

    在windows目录下再开启第二个cmd命令行窗口,执行如下命令将GDB文件上传到开发版/data目录下(可以是任意目录,gdb大小约70M)

     hdc_std file send gdb /data
    

OpenHarmony标准系统实践之GDB调试-鸿蒙开发者社区

发送成功后,可以回到第一个cmd窗口中看到/data目录下的GDB程序

OpenHarmony标准系统实践之GDB调试-鸿蒙开发者社区

备注:
有的开发板在上传时可能会报没有写权限,如果遇到,可在hdc_std shell中执行如下命令打开读写权限:

mount -o remount,rw /

2.3.2调试GDB

进入/data目录,先给gdb程序加上可执行权限:

chmod +x /data/gdb

然后运行/data/gdb,出现如下信息说明GDB已经可以正常使用了。
OpenHarmony标准系统实践之GDB调试-鸿蒙开发者社区

如果不想每次执行都带完整路径, 可以在系统默认运行路径 (/bin) 下给/data/gdb做一个软链接:

ln -s /data/gdb /bin/gdb

OpenHarmony标准系统实践之GDB调试-鸿蒙开发者社区

2.4 案例展示

Issue:zzcnative2的应用调用NAPI接口add(8,3),接口返回值预期是11,实际结果为5

以上述Issue为例,展示一下GDB调试的过程。
在开发板上加载运行zzcnative2应用,该应用包含部分c++的native代码,可以使用GDB对其进行调式。
OpenHarmony标准系统实践之GDB调试-鸿蒙开发者社区

  1. 找到需要跟踪的进程号。

    OpenHarmony的应用进程都是由应用孵化器(appspawn)创建的,可以先执行如下命令找到孵化器的进程号(92)。

     ps -ef | grep appspawn
    

    OpenHarmony标准系统实践之GDB调试-鸿蒙开发者社区

  2. 然后再找所有父进程为孵化器(92)的进程

     ps -ef | grep 92
    

    OpenHarmony标准系统实践之GDB调试-鸿蒙开发者社区

  3. 找到要调试的程序进程号(1167)后,执行如下命令运行GDB并挂到目标进程中

     gdb attach 1167
    

OpenHarmony标准系统实践之GDB调试-鸿蒙开发者社区

  1. 在需要的地方打上断点,然后让程序继续运行
    OpenHarmony标准系统实践之GDB调试-鸿蒙开发者社区
    在App上进行相关操作,触发断点所在的业务代码流程。
    OpenHarmony标准系统实践之GDB调试-鸿蒙开发者社区

    然后就可以开始各种调试手段了,如查看调用栈,打印变量,设置观测点等等,具体请参考GDB使用手册。

  2. 定位问题

    设置断点位置为Add入口,查看运行时入参value0、value1以及运行结果ret的值,发现逻辑与预期不一致,进一步使用list查看代码,发现“double ret = value0 – value1”符号错误,问题快速成功定位。
    OpenHarmony标准系统实践之GDB调试-鸿蒙开发者社区

    另外使用bt命令可打印调用栈信息,其他命令大家可以自己试一下。
    OpenHarmony标准系统实践之GDB调试-鸿蒙开发者社区

3. 总结

对于开发者来说,高效的调试手段至关重要,熟练使用GDB,可以帮忙大家提高代码走读、Issue定位效率,希望本次分享给大家一些启发,共同参与到OpenHarmony开发效率提升建设中。

更多原创内容请关注:深开鸿Kaihong

入门到精通、技巧到案例,系统化分享OpenHarmony开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2022-9-8 20:30:42修改
10
收藏 7
回复
举报
10条回复
按时间正序
/
按时间倒序
胡泉河_2021
胡泉河_2021

大佬,GDB工具是否通用的, 能上传一份吗?

回复
2022-9-9 09:31:08
FlashinMiami
FlashinMiami

GDB确实是调试神器

回复
2022-9-9 11:36:44
诺舒华吃西瓜
诺舒华吃西瓜

非常全面的GDB调试讲解

回复
2022-9-9 13:51:24
青舟321
青舟321

底层还是必须要用C或C++才更高效,不过确实对调试不太友好

回复
2022-9-9 17:54:26
wx60b25071502d0
wx60b25071502d0

gdb 32位工具包见附件

32bit_arm_gdb.zip 28.72M 97次下载
1
回复
2022-9-20 11:13:21
mb63297cfb39201
mb63297cfb39201

我尝试了一下,发现可能是由于GLIB的版本和作者的不一样,工具链和源码版本相同的情况下仍然编译失败,报“fntcl64无定义“,通过修改源码才勉强编译通过

回复
2022-9-20 16:56:41
wx634d33215efc1
wx634d33215efc1

请问编译好后,运行GDB直接报Signal 31退出是什么情况呢?包括

32bit_arm_gdb.zip里边解压出来的也是,master镜像

回复
2022-10-17 18:52:53
物联风景
物联风景

不错不错,很详细

回复
2022-10-18 14:59:14
wx5db6fc123fa8c
wx5db6fc123fa8c

gdb输入list命令无法显示源码

回复
2023-8-4 00:04:32
mb65a0a526904f5
mb65a0a526904f5

想问问能支持鸿蒙NEXT吗?


回复
2024-3-4 10:56:10
回复
    相关推荐