gdb调试QT程序
背景
最近自己使用第三方的屏幕在原子MP157开发板上测试,发现屏幕能够正常点亮,显示正常,但是主界面的触控却没有反应,因此怀疑TP的驱动IC是否有差异,TP驱动是否异常,所以开始了TP的调试工作。
首先对比原理图发现原子的4.3寸触摸屏使用的tp ic是gt9147,我购买的反客4.3寸屏幕驱动IC是gt911,两者的驱动程序均是内核自带的goodix.c驱动程序,同时兼容多款gt系列IC,然后使用自带的tslib相关测试程序测试发现两者均能够正常报点,且多点触控画图均没有问题,使用hexdump解析dev/input/event0的报点原数据,发现两者报点也均无差异,这就比较奇怪了,报点一样但是使用原子的屏幕就能正常使用,反客的就不行。然后就试了一下自己的buildroot QT测试程序发现使用反客屏幕就会触控屏幕就会触发段错误,原子的就不会。无奈,开启漫长调试路。
配置
因为使用反客屏幕触控会产生段错误,所以第一步就是生成core dump用于后续gdb解析。
首先执行如下指令,主要是为了产生core文件,一般默认情况下,core文件的大小被设置为0,这样系统就不dump出core文件了。这时,使用命令:ulimit -c unlimited进行设置,就可以把core文件的大小设置为无限大,同时也可以使用数字来替代unlimited,对core文件的上限制做更精确的设定。
ulimit -c unlimited
具体参考:
https://blog.csdn.net/phmatthaus/article/details/107182265
生成core dump
如下图所示,执行QT程序servo_self以后程序出现段错误,且在同目录下生成了core文件。
下面使用gdb对该dump文件进行解析,注意core文件和应用程序要处于同一目录:
arm-none-linux-gnueabihf-gdb servo_self core
结果提示找不到qt文件的symbols ,原因是编译QT程序servo_self的时候没有添加调试选项
can not find symbols from servo_self…
下面重新编译servo_self,在Makefile中如下部分添加-g选项
重新编译配置使用gdb解析,继续报错,提示找不到共享库的符号表
使用info sharedlibrary 指令查看当前确实的共享库路径:
使用 solib-search-path指定这些NO的共享库路径:
set solib-search-path /home/tangtao/work/nfs/rootfs/lib/:/home/tangtao/work/nfs/rootfs/usr/lib/:/home/tangtao/work/nfs/rootfs/usr/lib/qt/plugins/platforms/
发现原来是这些so编译的时候没有带调试信息。。。。还需要重新使用buildroot编译QT添加-g调试选项。无奈,重新编译buildroot,解压到的我网络文件系统中去。。重新解析dump
重新编译生成QT共享库
第一种方法:
直接在buildroot/output/build/qt5base-5.12.8源代码下修改qmake conf里面的CC CXX LINK定义,如下图所示
修改完以后直接在buildroot根目录下执行make 是不会重新编译的,需要进入到qt5base-5.12.8包里面删除.stamp_built 和.stamp_target_install文件,然后编译QT包,最后sudo make打包到整个根文件系统中去。如下图:sudo make show-targets可以显示当前buildroot有哪些包,可以sudo make qt5base单编qt,然后sudo make打包
第二种方法:
第一种方法由于是修改output下面的内容,单独编译QT没有问题,但是以后有修改buildroot其他包很容易clean掉我们的修改,因此正确做法是根据需要修改的内容去制作补丁放到特定的位置,这样以后每次编译才会带上我们的修改。
cd buildroot/output/build
cp qt5base-5.12.8/mkspecs/linux-arm-gnueabi-g++/qmake.conf ./tmp
修改tmp/qmake.conf添加上-g调试选项
sudo diff -uNr qt5base-5.12.8/mkspecs/linux-arm-gnueabi-g++/qmake.conf tmp/qmake.conf > 0004-add_debug.patch
mv 0004-add_debug.patch ../../package/qt5/qt5base/5.12.8/
通过上面两种方法都编译得到了最新的根文件系统,在output/images下有rootfs.tar,可以ls -la看下生成时间是不是最新的。拷贝output/images/rootfs.tar到我们网络文件系统里面去,tar -vxf rootfs.tar解压即可
下面继续测试: