项目场景:
程序跑在离线的开发板上,新功能频繁导致导致崩溃,报错信息无法准确定位到实际出问题的位置,加太多打印也不现实,考虑使用 valgrind 进行调试。
软件安装
Valgrind
官方版本:Current Releases
OpenEuler 版本: src-openEuler/valgrind
安装流程参考以下命令
$ mkdir /tmp/valgrind
$ cp valgrind-3.22.0.tar.bz2 /tmp/valgrind/
$ cd /tmp/valgrind
$ bzip2 -d valgrind-3.22.0.tar.bz2
$ tar -xf valgrind-3.22.0.tar.bz2
$ cd valgrind-3.22.0
$ ./configure && make
$ sudo make install
安装完成尝试调试程序的时候我们很可能见到这样的错误提示
==21276== Memcheck, a memory error detector
==21276== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==21276== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
==21276== Command: ls
==21276==
valgrind: Fatal error at startup: a function redirection
valgrind: which is mandatory for this platform-tool combination
valgrind: cannot be set up. Details of the redirection are:
valgrind:
valgrind: A must-be-redirected function
valgrind: whose name matches the pattern: strlen
valgrind: in an object with soname matching: ld-linux-x86-64.so.2
valgrind: was not found whilst processing
valgrind: symbols from the object with soname: ld-linux-x86-64.so.2
valgrind:
valgrind: Possible fixes: (1, short term): install glibc's debuginfo
valgrind: package on this machine. (2, longer term): ask the packagers
valgrind: for your Linux distribution to please in future ship a non-
valgrind: stripped ld.so (or whatever the dynamic linker .so is called)
valgrind: that exports the above-named function using the standard
valgrind: calling conventions for this platform. The package you need
valgrind: to install for fix (1) is called
valgrind:
valgrind: On Debian, Ubuntu: libc6-dbg
valgrind: On SuSE, openSuSE, Fedora, RHEL: glibc-debuginfo
valgrind:
valgrind: Note that if you are debugging a 32 bit process on a
valgrind: 64 bit system, you will need a corresponding 32 bit debuginfo
valgrind: package (e.g. libc6-dbg:i386).
valgrind:
valgrind: Cannot continue -- exiting now. Sorry.
解决方法也很简单,安装对应 glibc-debuginfo
即可
glibc-debuginfo
首先确定系统 glibc
版本
$ ldd -version
ldd (GNU libc) 2.28
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.
一般来说保证相关库版本和查询到的版本一致即可,但 valgrind
对相关库要求更严格,我们需要查看更详细的版本信息
$ rpm -qa | grep glibc
glibc-common-2.28-36.oe1.x86_64
glibc-devel-2.28-36.oe1.x86_64
glibc-2.28-36.oe1.x86_64
可以看到我们需要的版本应该是 2.28-36.oe1.x86_64
,需要注意的是这里需要保证版本完全一致,即 oe1
也需要一样,否则 valgrind
仍将报同样的错误。从不同镜像找到的版本将会各有不同,这里我们需要的版本可以在在 repo.huaweicloud.com/openeuler 找到
$ cp glibc-debuginfo-2.28-36.oe1.x86_64.rpm /tmp/valgrind/
$ cd /tmp/valgrind/
$ rmp -i glibc-debuginfo-2.28-36.oe1.x86_64.rpm
代码调试
假设我们有如下程序
#include <stdlib.h>
int main()
{
int *array = malloc(sizeof(int));
return 0;
}
编译并使用 valgrind
调试
$ gcc -g -o main_c main.c
$ valgrind --tool=memcheck --leak-check=full ./main_c
==31416== Memcheck, a memory error detector
==31416== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==31416== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==31416== Command: ./main_c
==31416==
==31416==
==31416== HEAP SUMMARY:
==31416== in use at exit: 4 bytes in 1 blocks
==31416== total heap usage: 1 allocs, 0 frees, 4 bytes allocated
==31416==
==31416== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1
==31416== at 0x4C2DBF6: malloc (vg_replace_malloc.c:299)
==31416== by 0x400537: main (main.c:5)
==31416==
==31416== LEAK SUMMARY:
==31416== definitely lost: 4 bytes in 1 blocks
==31416== indirectly lost: 0 bytes in 0 blocks
==31416== possibly lost: 0 bytes in 0 blocks
==31416== still reachable: 0 bytes in 0 blocks
==31416== suppressed: 0 bytes in 0 blocks
==31416==
==31416== For counts of detected and suppressed errors, rerun with: -v
==31416== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
可以看到提供了很详细的信息帮助我们定位问题所在,至此我们完成了 valgrind
的安装及使用,更进阶的相关使用可查看官方文档 Valgrind User Manual
其他碎碎念
查看系统信息
确定所需软件版本。
$ cat /etc/os-release
NAME="openEuler"
VERSION="20.03 (LTS)"
ID="openEuler"
VERSION_ID="20.03"
PRETTY_NAME="openEuler 20.03 (LTS)"
ANSI_COLOR="0;31"
Linux 自带 coredump
Linux 系统自身提供了一些功能帮助我们来进行复盘和调试
$ ulimit -c unlimited # 启用系统 coredump 功能
$ coredumpctl list # 查看最近的崩溃日志
TIME PID UID GID SIG COREFILE EXE
......
$ coredumpctl dump # 查看最近一次崩溃的详细信息
$ coredumpctl debug # 程序重新以 -g 编译后可直接尝试 debug
Qt 远程调试
Qt 自身也提供远程调试方式 Tools -> Options -> Devices
,配置参考下图,设备上添加对应公钥即可
点击右侧 Test
按钮查看是否连接成功
成功后直接 Debug
即可,如出现编译错误 missing -lGL
,可以考虑修改 pro
文件,或安装对应库
QT -= gui
希望对你有所帮助