交叉编译valgrind在嵌入式设备上调试程序

简介: 交叉编译valgrind在嵌入式设备上调试程序

valgrind是一个很好的内存检测工具,可以让程序员避免用“瞪眼法”去定位内存泄露问题。下面记录一下本人在arm64上使用valgrind的过程。

目录
1.下载最新版本的valgrind源码
2.解压
3.编译
4.打包
4.运行
5.报错及解决方法
1.下载最新版本的valgrind源码
https://sourceware.org/ftp/valgrind/

2.解压
tar -xjf valgrind-3.23.0.tar.bz2
3.编译
(1)valgrind早已经准备了不同平台的编译说明,进入目录找到对应平台的readme

README
README.aarch64
README.android
README.android_emulator
README_DEVELOPERS
README_DEVELOPERS_processes
README.freebsd
README.mips
README_MISSING_SYSCALL_OR_IOCTL
README_PACKAGERS
README.s390
README.solaris
(2)我的是aarch64,参考README.aarch64,为了方便把编译命令写入脚本

$ vim build.sh

!/bin/bash

export CC=aarch64-gnu-linux-gcc
export CXX=aarch64-gnu-linux-g++
export AR=aarch64-gnu-linux-ar
export RANLIB=aarch64-gnu-linux-ranlib
export STRIP=aarch64-gnu-linux-strip
export LD=aarch64-gnu-linux-ld
export NM=aarch64-gnu-linux-nm
export AS=aarch64-gnu-linux-as
export CFLAGS="--sysroot=/path/to/toolchain/sysroots/aarch64-gnu-linux -g"$CFLAGS
export CXXFLAGS="--sysroot=/path/to/toolchain/sysroots/aarch64-gnu-linux -g"$CXXFLAGS
export LDFLAGS="--sysroot=/path/to/toolchain/sysroots/aarch64-gnu-linux "$LDFLAGS

./autogen.sh
./configure --prefix=/tmp/ins --host=aarch64-gnu-linux \
--enable-only64bit
make -j4
make -j4 install
在执行这个脚本之前,需要切换到交叉编译环境,不同的平台有不同的方法。

source env-setup-aarch64-gnu-linux
执行脚本:

chmod 777 build.sh
./build.sh
从脚本中可以看到,比README多了一些东西,其中AR、RANLIB等,是编译其他工程时的参数,直接复制过来的,在这用不到。
CFLAGS里的--sysroot指定了目标平台系统的头文件和库文件的搜索路径,如果编译不成功,不妨加上这个参数试试。

4.打包
在上一步中--prefix指定的是/tmp/ins,所以

cd /tmp/
tar -zcvf ins.tar.gz ins/
传到自己的开发板上

scp ins.tar.gz root@192.168.1.33:/tmp/
注意,最好把包解压到和prefix指定的相同的路径里。

4.运行
export VALGRIND_LIB=/tmp/ins/libexec/valgrind
/tmp/ins/bin/valgrind --tool=memcheck --leak-check=yes --log-file=valgrind_output.txt ./mydemo ${ARG1} "${ARG2}"
--leak-check表示检测内存泄露
--log-file是将结果输出到文件
mydemo是自己写的demo程序
${ARG1}、${ARG2}是mydemo的参数

5.报错及解决方法
1."valgrind: failed to start tool 'memcheck' for platform 'arm64-linux': No such file or directory"

解决方法:需要执行之前指定VALGRIND_LIB的路径,记住是libexec的路径:

export VALGRIND_LIB=/tmp/ins/libexec/valgrind
2.执行时被退出

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-aarch64.so.1
valgrind: was not found whilst processing
valgrind: symbols from the object with soname: ld-linux-aarch64.so.1
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.
解决方法:

sudo apt-get install libc6-dbg
可惜,苦命的打工人在调试的时候,用的板子哪会有yum、apt-get、dplg那些东西?

还有人说自己编译glibc,不知道你成没成功,反正我交叉编译glibc没能成功。就算成功了,把libc库直接换到你的系统里,如果最后弄得ssh都用不了,哭都来不及。

更何况,我已经给mydemo编译的时候加了-g选项,还要我再安装libc6-dbg,你不觉的有些过分么?大不了我不看libc里的堆栈内容就行了,何必强人所难?

最终找到了解决方法:修改valgrind源码,把报错地方的VG_(exit)注释掉,重新编译valgrind,世界终于清净了。

963 "%sCannot continue -- exiting now. Sorry.\n", v);
964 VG(printf)("\n");
965 //VG
(exit)(1);
神挡杀神,佛挡杀佛,如果还有别处报错也注释掉。

1914 VG(printf)(
1915 "%sCannot continue -- exiting now.\n", v);
1916 VG
(printf)("\n");
1917 //VG_(exit)(1);
最后运行出来的结果是这样的,那些本来也不用去看的第三方库文件显示"?"完全可以接受。

==3219788== 4,096 bytes in 2 blocks are possibly lost in loss record 12,024 of 12,306
==3219788== at 0x74F66B8: malloc (vg_replace_malloc.c:446)
==3219788== by 0x85A71AB: PL_ArenaAllocate (in /usr/lib/libplds4.so)
{spa.hangyi360.com]
{spa.zhemwu.com]
{spa.hikarieakon.com]
{spa.daniuruanjian.com]
{spa.lyzxxc.com]
{spa.murabayashi-k.com]
{spa.fcw7070.com]
==3219788== by 0x7AA0F43: ??? (in /usr/lib/libnss3.so)
==3219788== by 0x7AA1157: ??? (in /usr/lib/libnss3.so)
==3219788== by 0x7A5457F: ??? (in /usr/lib/libnss3.so)
==3219788== by 0x7A9AE27: ??? (in /usr/lib/libnss3.so)
==3219788== by 0x7A9AF93: ??? (in /usr/lib/libnss3.so)
==3219788== by 0x7A41D1F: ??? (in /usr/lib/libnss3.so)
==3219788== by 0x7A42413: NSS_InitReadWrite (in /usr/lib/libnss3.so)
==3219788== by 0x26C6E73: crypto::(anonymous namespace)::NSSInitSingleton::NSSInitSingleton() (in mydemo)
==3219788== by 0x26C756B: crypto::EnsureNSSInit() (in mydemo)
==3219788== by 0x25C5963: net::CertDatabase::GetInstance() (in mydemo)

相关文章
|
监控 NoSQL Linux
深入Linux内存泄漏排查:Valgrind与系统工具的联合应用
深入Linux内存泄漏排查:Valgrind与系统工具的联合应用
1600 0
|
测试技术 程序员 C++
C++单元测试GoogleTest和GoogleMock十分钟快速上手(gtest&gmock)
gtest是Google开源的一个跨平台的(Liunx、Mac OS X、Windows等)的 C++ 单元测试框架,可以帮助程序员测试 C++ 程序的结果预期。它提供了丰富的断言、致命和非致命判断、参数化、”死亡测试”等等。另一方面,gmock并不是一个独立的测试框架,而是gtest的辅助框架,主要用于模拟没有实现的类的操作,以便在没有完整类的情况下进行测试。通过配合使用gtest和gmock,开发者可以编写出更为复杂且健壮的C++单元测试。
2518 0
|
Linux
Linux(5)WIFI/BT调试笔记
Linux(5)WIFI/BT调试笔记
2314 0
|
安全 Linux 编译器
内存泄漏检测组件的分析与实现(linux c)-mtrace工具使用
内存泄漏产生原因 在堆上使用malloc/remalloc/calloc分配了内存空间,但是没有使用free释放对应的空间。
585 0
|
监控 物联网 数据安全/隐私保护
蓝牙调试工具集合汇总
蓝牙调试工具集合汇总
1401 0
|
数据安全/隐私保护 块存储
|
IDE Linux 开发工具
内存泄漏检测工具Valgrind:C++代码问题检测的利器(一)
内存泄漏检测工具Valgrind:C++代码问题检测的利器
3817 0
|
C++ 索引
vscode clangd c++开发常见问题和解决方案
vscode clangd c++开发常见问题和解决方案
4350 0
|
缓存 Linux iOS开发
【C/C++ 集成内存调试、内存泄漏检测和性能分析的工具 Valgrind 】Linux 下 Valgrind 工具的全面使用指南
【C/C++ 集成内存调试、内存泄漏检测和性能分析的工具 Valgrind 】Linux 下 Valgrind 工具的全面使用指南
3412 1
|
存储 编解码
FFmpeg开发笔记(三十)解析H.264码流中的SPS帧和PPS帧
《FFmpeg开发实战》书中介绍了音视频编码历史,重点讲述H.264的成功在于其分为视频编码层和网络抽象层。H.264帧类型包括SPS(序列参数集,含视频规格参数),PPS(图像参数集,含编码参数)和IDR帧(立即解码刷新,关键帧)。SPS用于计算视频宽高和帧率,PPS存储编码设置,IDR帧则标志新的解码序列。书中还配以图片展示各帧结构详情,完整内容可参考相关书籍。
1688 7
FFmpeg开发笔记(三十)解析H.264码流中的SPS帧和PPS帧