交叉编译valgrind(9x07)
1 介绍
valgrind 是一套 Linux 下,开放源代码的动态调试工具集合,能够检测内存管理错误、线程 BUG 等,valgrind 由内核(core)以及基于内核的其他调试工具组成。内核类似于一个框架(framework),它模拟了一个 CPU 环境,并提供服务给其他工具;而其他工具则类似于插件 (plug-in),利用内核提供的服务完成各种特定的内存调试任务。
valgrind 包括的工具如下:
- Memcheck是一个内存错误检测器。 它可以帮助您使程序,尤其是那些用C和C ++编写的程序更加正确。
- Cachegrind是缓存和分支预测分析器。 它可以帮助您使程序运行得更快。
- Callgrind是一个生成缓存分析器的调用图。 它与Cachegrind有一些重叠,但也收集了Cachegrind没有的一些信息。
- Helgrind是一个线程错误检测器。 它可以帮助您使多线程程序更正确。
- DRD也是线程错误检测器。 它与Helgrind类似,但使用不同的分析技术,因此可能会发现不同的问题。
- Massif是一个堆分析器。 它可以帮助您使程序使用更少的内存。
- DHAT是一种不同类型的堆分析器。 它可以帮助您了解块寿命,块利用率和布局效率低下的问题。
- SGcheck是一种实验工具,可以检测堆栈和全局数组的溢出。 它的功能与Memcheck的功能互补:SGcheck发现Memcheck无法解决的问题,反之亦然。
- BBV是一个实验性的SimPoint基本块矢量生成器。 它对进行计算机体系结构研究和开发的人很有用。
2 交叉编译(arm-oe-linux-gnueabi)
2.1 前期准备
务必注意看自己的平台是否支持,我的设备通过检查是armv7l,是支持的。
uname -a
Linux mdm9607-perf 3.18.20 #36 PREEMPT Thu Jan 27 17:18:04 CST 2022 armv7l GNU/Linux
详情看官方介绍:Valgrind: Supported Platforms
Valgrind supports the following platforms:
- x86/Linux: up to and including SSSE3, but not higher – no SSE4, AVX, AVX2. This target is in maintenance mode now…
- AMD64/Linux: up to and including AVX2. This is the primary development target and tends to be well supported.
- PPC32/Linux, PPC64/Linux, PPC64LE/Linux: up to and including Power8.
- S390X/Linux: supported.
- ARM/Linux: supported since ARMv7.
- ARM64/Linux: supported for ARMv8.
- MIPS32/Linux, MIPS64/Linux: supported.
- X86/FreeBSD, AMD64/FreeBSD: supported since FreeBSD 11.3.
- X86/Solaris, AMD64/Solaris, X86/illumos, AMD64/illumos: supported since Solaris 11.
- X86/Darwin (10.5 to 10.13), AMD64/Darwin (10.5 to 10.13): supported.
- ARM/Android, ARM64/Android, MIPS32/Android, X86/Android: supported.
On Linux, you must be running kernel 3.0 or later, and glibc 2.5.X or later.
On Mac OS X you must be running 10.9.x or later.
For details of which distributions the current release (valgrind-3.20.0) builds and runs its regression tests on, see the release notes.
下载
1、下载 valgrind (https://www.valgrind.org/downloads/或者Index of /pub/valgrind (sourceware.org))
2、解压缩,输入指令解压
tar -jxvf valgrind-3.20.0.tar.bz2
3、进入解压后的目录中
cd valgrind-3.20.0
2.2 环境配置
先修改 configure 脚本
将 armv7* 改为 armv7*|arm
# 否则将出现configure: error: Unsupported host architecture. Sorry错误
然后按照下面执行(根据自己的交叉编译环境修改),prefix改为自己要保存的编译后的文件目录,绝对路径。
# 配置编译环境
./configure --host=arm-oe-linux-gnueabi CC=arm-oe-linux-gnueabi-gcc CPP=arm-oe-linux-gnueabi-cpp CXX=arm-oe-linux-gnueabi-g++ AR=arm-oe-linux-gnueabi-ar LD=arm-oe-linux-gnueabi-ld --prefix=$PWD/valgrind
执行结果
Version: 3.20.0
Maximum build arch: arm
Primary build arch: arm
Secondary build arch:
Build OS: linux
Link Time Optimisation: no
Primary build target: ARM_LINUX
Secondary build target:
Platform variant: vanilla
Primary -DVGPV string: -DVGPV_arm_linux_vanilla=1
Default supp files: ./xfree-3.supp ./xfree-4.supp glibc-2.X-drd.supp glibc-2.X-helgrind.supp glibc-2.X.supp
然后编译
make -j4
# install也可以指定目录 make -j4 install DESTDIR=`pwd`/valgrind
make -j4 install
会在 --prefix 指定的目录下生成四个子目录:bin、include、lib、libexec 和 share,我们需要的 valgrind 工具就在其中的bin目录下。
valgrind
├── bin # 工具可执行文件所在目录
│ ├── callgrind_annotate
│ ├── callgrind_control
│ ├── cg_annotate
│ ├── cg_diff
│ ├── cg_merge
│ ├── ms_print
│ ├── valgrind
│ ├── valgrind-di-server
│ ├── valgrind-listener
│ └── vgdb
├── include # 头文件所在目录
│ └── valgrind
├── lib # 执行所需要的库目录
│ ├── pkgconfig
│ └── valgrind
├── libexec # 包含不由用户和shell script直接执行的二进制文件,比如某些特定库需要某些可执行文件,但是这些可执行文件不是由用户直接调用或由root调用的,则它们位于libexec中
│ └── valgrind
└── share # 文档帮助文件
├── doc
└── man
3 使用
3.1 拷贝到设备并设置环境变量
动态库在valgrind/libexec/valgrind里面,所以把valgrind/libexec/valgrind中所有文件拷贝到valgrind/lib,可以把不用的删掉,比如静态库之类的,然后打包bin和lib并推送到设备就行了。
# 先拷贝到/mnt/sdidk/valgrind目录下,目录自己定
tar -czvf valgrind.tar.gz valgrind/bin/* valgrind/lib/*
adb push valgrind.tar.gz /mnt/sdisk/valgrind
cd /mnt/sdisk/valgrind && tar -zxvf valgrind.tar.gz
# 然后配置环境变量,本次有效,方便直接使用命令
export PATH="$PATH:/mnt/sdisk/valgrind/bin"
# 配置工具库变量
export VALGRIND_LIB="/mnt/sdisk/valgrind/lib/valgrind"
3.2 执行
可输入以下指令测试 valgrind 是否可以正常运行,如果出现一大堆选项解释,则表示成功
valgrind --version
valgrind-3.20.0
通过检查内存泄漏的问题使用(./sample为可执行程序名,为了使valgrind发现的错误更精确,建议在编译时加上-g参数,编译优化选项请选择O0):
valgrind -v --error-limit=no --leak-check=full --tool=memcheck ./sample
3.3 运行时遇到ld-linux.so.3问题
运行检查时发现ld-linux.so.3问题,具体如下:
==31877== Memcheck, a memory error detector
==31877== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==31877== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==31877== Command: /mnt/flash/app/monitor.exe
==31877==
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: index
valgrind: in an object with soname matching: ld-linux.so.3
valgrind: was not found whilst processing
valgrind: symbols from the object with soname: ld-linux.so.3
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.
原因是设备中的ld-linux.so.3是strip过的,解决办法是,从交叉编译环境中找到并替换到设备中没有strip过的ld-linux.so.3解决问题。
可以通过file命令查看库是否strip过:
file ./ql-ol-crosstool/sysroots/armv7a-vfp-neon-oe-linux-gnueabi/lib/ld-2.21.so
./ql-ol-crosstool/sysroots/armv7a-vfp-neon-oe-linux-gnueabi/lib/ld-2.21.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, with debug_info, not stripped
3.4 运行选项
(1)适用于所有Valgrind工具
–tool=< name > 最常用的选项。运行 valgrind中名为toolname的工具。默认memcheck。
-h --help 显示帮助信息。
–version 显示valgrind内核的版本,每个工具都有各自的版本。
-q --quiet 安静地运行,只打印错误信息。
-v --verbose 更详细的信息, 增加错误数统计。
–trace-children=no|yes 跟踪子线程? [no]
–track-fds=no|yes 跟踪打开的文件描述?[no]
–time-stamp=no|yes 增加时间戳到LOG信息? [no]
–log-fd=< number > 输出LOG到描述符文件 [2=stderr]
–log-file=< file > 将输出的信息写入到filename.PID的文件里,PID是运行程序的进行ID
–log-file-exactly=< file > 输出LOG信息到 file
–log-file-qualifier=< VAR > 取得环境变量的值来做为输出信息的文件名。 [none]
–log-socket=ipaddr:port 输出LOG到socket ,ipaddr:port
(2)LOG信息输出
–xml=yes 将信息以xml格式输出,只有memcheck可用
–num-callers=< number > show < numbe r> callers in stack traces [12]
–error-limit=no|yes 如果太多错误,则停止显示新错误? [yes]
–error-exitcode=< number > 如果发现错误则返回错误代码 [0=disable]
–db-attach=no|yes 当出现错误,valgrind会自动启动调试器gdb。[no]
–db-command=< command > 启动调试器的命令行选项[gdb -nw %f %p]
(3)适用于Memcheck工具的相关选项:
–leak-check=no|summary|full 要求对leak给出详细信息? [summary]
–leak-resolution=low|med|high how much bt merging in leak check [low]
–show-reachable=no|yes show reachable blocks in leak check? [no]
更详细的使用信息详见帮助文件、man手册或官网:http://valgrind.org/docs/manual/manual-core.html
(4)注意:
① valgrind不会自动的检查程序的每一行代码,只会检查运行到的代码分支,所以单元测试或功能测试用例很重要;
② 可以把valgrind看成是一个sandbox,通过valgrind运行的程序实际上是运行在valgrind的sandbox中的,所以,不要测试性能,会让你失望的,建议只做功能测试
③ 编译代码时,建议增加-g -o0选项,不要使用-o1、-o2选项
4 参考
Valgrind交叉编译(踩坑)_阿木_123的博客-CSDN博客
更多推荐
所有评论(0)