Valgrind arm-linux 交叉编译


Valgrind是用于构建动态分析工具的仪器框架。 它附带了一组工具,每个工具都执行某种调试,分析或类似任务,可帮助您改进程序。

Valgrind的架构采用模块化设计,因此可以轻松创建新工具,而不会干扰现有结构。

开始工作前,有两项信息不得不看,那就是平台和工具概述,虽然百度查了一些,但毕竟不如官方的准确:

平台支持,我的 ARM-v7 是支持的

http://valgrind.org/info/platforms.html

工具概述:

http://valgrind.org/info/tools.html

标准配置提供了许多有用的工具。

  1. Memcheck是一个内存错误检测器。 它可以帮助您使程序,尤其是那些用C和C ++编写的程序更加正确。

  2. Cachegrind是缓存和分支预测分析器。 它可以帮助您使程序运行得更快。

  3. Callgrind是一个生成缓存分析器的调用图。 它与Cachegrind有一些重叠,但也收集了Cachegrind没有的一些信息。

  4. Helgrind是一个线程错误检测器。 它可以帮助您使多线程程序更正确。

  5. DRD也是线程错误检测器。 它与Helgrind类似,但使用不同的分析技术,因此可能会发现不同的问题。

  6. Massif是一个堆分析器。 它可以帮助您使程序使用更少的内存。

  7. DHAT是一种不同类型的堆分析器。 它可以帮助您了解块寿命,块利用率和布局效率低下的问题。

  8. SGcheck是一种实验工具,可以检测堆栈和全局数组的溢出。 它的功能与Memcheck的功能互补:SGcheck发现Memcheck无法解决的问题,反之亦然。

  9. BBV是一个实验性的SimPoint基本块矢量生成器。 它对进行计算机体系结构研究和开发的人很有用。

其中官方解释到:

Memcheck检测内存管理问题,主要针对C和C ++程序。Memcheck运行程序比正常情况慢大约10-30倍

Cachegrind运行程序比正常情况慢大约20-100倍。

Massif运行程序比正常情况慢20倍

1.下载源码

http://valgrind.org/

2 解压后进行配置:

./configure --prefix=/home/sun/share/install --host=arm-buildroot-linux-uclibcgnueabi

配置报错:

checking for a supported CPU... no (arm)
configure: error: Unsupported host architecture. Sorry

查看官方网站首页,发现对 ARM-LINUX 是支持的

It also includes three experimental tools: a stack/global array overrun detector, a second heap profiler that examines how heap blocks are used, and a SimPoint basic block vector generator. It runs on the following platforms: X86/Linux, AMD64/Linux, ARM/Linux, ARM64/Linux, PPC32/Linux, PPC64/Linux, PPC64LE/Linux, S390X/Linux, MIPS32/Linux, MIPS64/Linux, X86/Solaris, AMD64/Solaris, ARM/Android (2.3.x and later), ARM64/Android, X86/Android (4.0 and later), MIPS32/Android, X86/Darwin and AMD64/Darwin (Mac OS X 10.12).

修改 configure 文件:

armv7a* 改为 arm* 再次配置就不会报错了

修改前:

修改后:

3.编译

make -j4
make install

会生成四个目录:bin lib share include

4.我的板子空间非常小,所以需要删除不需要的工具,只留下内存检查工具,

需要删除 lib/valgrind 目录下的文件 以及 整个 share 目录,最后精简到 12M 左右:

sun@machine:~/share/install$ du -sh bin include/ lib/
520K    bin
2.1M    include/
10M    lib/

精简后的lib/valgrind 目录下所有文件:

32bit-core-valgrind-s1.xml  32bit-sse.xml                arm-with-vfpv3.xml
32bit-core-valgrind-s2.xml  arm-core-valgrind-s1.xml    default.supp
32bit-core.xml              arm-core-valgrind-s2.xml    getoff-arm-linux
32bit-linux-valgrind-s1.xml  arm-core.xml                memcheck-arm-linux
32bit-linux-valgrind-s2.xml  arm-vfpv3-valgrind-s1.xml    vgpreload_core-arm-linux.so
32bit-linux.xml              arm-vfpv3-valgrind-s2.xml    vgpreload_memcheck-arm-linux.so
32bit-sse-valgrind-s1.xml    arm-vfpv3.xml
32bit-sse-valgrind-s2.xml    arm-with-vfpv3-valgrind.xml

 

文件名含有 ARM-LINUX 字样的文件信息:

sun@machine:~/share/install/lib/valgrind$ file *arm-linux*
getoff-arm-linux:                ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-uClibc.so.0, with debug_info, not stripped
memcheck-arm-linux:              ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, with debug_info, not stripped
vgpreload_core-arm-linux.so:    ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, with debug_info, not stripped
vgpreload_memcheck-arm-linux.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, with debug_info, not stripped

5.对于运行环境的要求:

 

http://valgrind.org/docs/manual/dist.readme-packagers.html

7. README_PACKAGERS

Greetings, packaging person!  This information is aimed at people
building binary distributions of Valgrind.

Thanks for taking the time and effort to make a binary distribution of
Valgrind.  The following notes may save you some trouble.

-- If your toolchain (compiler, linker) support lto, using the configure
  option --enable-lto=yes will produce a smaller/faster valgrind
  (up to 10%).

-- Do not ship your Linux distro with a completely stripped
  /lib/ld.so.  At least leave the debugging symbol names on -- line
  number info isn't necessary.  If you don't want to leave symbols on
  ld.so, alternatively you can have your distro install ld.so's
  debuginfo package by default, or make ld.so.debuginfo be a
  requirement of your Valgrind RPM/DEB/whatever.

  Reason for this is that Valgrind's Memcheck tool needs to intercept
  calls to, and provide replacements for, some symbols in ld.so at
  startup (most importantly strlen).  If it cannot do that, Memcheck
  shows a large number of false positives due to the highly optimised
  strlen (etc) routines in ld.so.  This has caused some trouble in
  the past.  As of version 3.3.0, on some targets (ppc32-linux,
  ppc64-linux), Memcheck will simply stop at startup (and print an
  error message) if such symbols are not present, because it is
  infeasible to continue.

  It's not like this is going to cost you much space.  We only need
  the symbols for ld.so (a few K at most).  Not the debug info and
  not any debuginfo or extra symbols for any other libraries.


-- (Unfortunate but true) When you configure to build with the
  --prefix=/foo/bar/xyzzy option, the prefix /foo/bar/xyzzy gets
  baked into valgrind.  The consequence is that you _must_ install
  valgrind at the location specified in the prefix.  If you don't,
  it may appear to work, but will break doing some obscure things,
  particularly doing fork() and exec().

  So you can't build a relocatable RPM / whatever from Valgrind.


-- Don't strip the debug info off lib/valgrind/$platform/vgpreload*.so
  in the installation tree.  Either Valgrind won't work at all, or it
  will still work if you do, but will generate less helpful error
  messages.  Here's an example:

  Mismatched free() / delete / delete []
      at 0x40043249: free (vg_clientfuncs.c:171)
      by 0x4102BB4E: QGArray::~QGArray(void) (tools/qgarray.cpp:149)
      by 0x4C261C41: PptDoc::~PptDoc(void) (include/qmemarray.h:60)
      by 0x4C261F0E: PptXml::~PptXml(void) (pptxml.cc:44)
      Address 0x4BB292A8 is 0 bytes inside a block of size 64 alloc'd
      at 0x4004318C: __builtin_vec_new (vg_clientfuncs.c:152)
      by 0x4C21BC15: KLaola::readSBStream(int) const (klaola.cc:314)
      by 0x4C21C155: KLaola::stream(KLaola::OLENode const *) (klaola.cc:416)
      by 0x4C21788F: OLEFilter::convert(QCString const &) (olefilter.cc:272)

  This tells you that some memory allocated with new[] was freed with
  free().

  Mismatched free() / delete / delete []
      at 0x40043249: (inside vgpreload_memcheck.so)
      by 0x4102BB4E: QGArray::~QGArray(void) (tools/qgarray.cpp:149)
      by 0x4C261C41: PptDoc::~PptDoc(void) (include/qmemarray.h:60)
      by 0x4C261F0E: PptXml::~PptXml(void) (pptxml.cc:44)
      Address 0x4BB292A8 is 0 bytes inside a block of size 64 alloc'd
      at 0x4004318C: (inside vgpreload_memcheck.so)
      by 0x4C21BC15: KLaola::readSBStream(int) const (klaola.cc:314)
      by 0x4C21C155: KLaola::stream(KLaola::OLENode const *) (klaola.cc:416)
      by 0x4C21788F: OLEFilter::convert(QCString const &) (olefilter.cc:272)

  This isn't so helpful.  Although you can tell there is a mismatch,
  the names of the allocating and deallocating functions are no longer
  visible.  The same kind of thing occurs in various other messages
  from valgrind.


-- Don't strip symbols from lib/valgrind/* in the installation tree.
  Doing so will likely cause problems.  Removing the line number info is
  probably OK (at least for some of the files in that directory), although
  that has not been tested by the Valgrind developers.


-- Please test the final installation works by running it on something
  huge.  I suggest checking that it can start and exit successfully
  both Firefox and OpenOffice.org.  I use these as test programs, and I
  know they fairly thoroughly exercise Valgrind.  The command lines to use
  are:

  valgrind -v --trace-children=yes firefox

  valgrind -v --trace-children=yes soffice


If you find any more hints/tips for packaging, please report
it as a bugreport. See http://www.valgrind.org for details.

里面提到五个重要的事项:

1 - 如果您的工具链(编译器,链接器)支持lto,则使用configure 选项--enable-lto = yes将产生更小/更快的valgrind

2 - 不要使用完全剥离的Linux发行版/lib/ld.so。(比如上面的getoff-arm-linux 就链接了 /lib/ld-uClibc.so.0, 那就要求我们的开发板根目录下的  /lib/ld-uClibc.so.0 必须是 not stripped)

3 在开发板上面运行的目录必须与 --prefix = 指定的目录完全一致
 
4 - 不要将调试信息从lib / valgrind / $ platform / vgpreload * .so中删除(比如上面的vgpreload_core-arm-linux.so 和 vgpreload_memcheck-arm-linux.so 必须是 not stripped)

5 - 不要在安装树中从lib / valgrind / *中删除符号。(比如上面的getoff-arm-linux 和 memcheck-arm-linux  必须是 not stripped)

第 4、5 两条就要求我们 lib/valgrind/ 目录下的任何文件都必须是 not stripped,这样才能保证程序可靠

将所有精简后的目录放到开发板的指定目录(即--prefix=/home/sun/share/install 这个目录),如果你忘记了当时编译的目录是哪个,请查看 lib/pkgconfig/valgrind.pc

 文件内有绝对路径的说明:如 prefix=/home/sun/share/install 

sun@machine:~/share/install/lib/pkgconfig$ cat valgrind.pc
prefix=/home/sun/share/install
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include/valgrind
arch=arm
os=linux
platform=arm-linux
valt_load_address=0x58000000

Name: Valgrind
Description: A dynamic binary instrumentation framework
Version: 3.14.0
Requires:
Libs: -L${libdir}/valgrind -lcoregrind-arm-linux -lvex-arm-linux -lgcc
Cflags: -I${includedir}

一般情况下都可以成功运行,偶尔adb push 进去后不能运行,如果已经确定在开发板上面的路径与prefix 指定的路径完全一致了,但依然报以下错误:

valgrind: failed to start tool 'memcheck' for platform 'arm-linux': No such file or directory

那就需要指定库的路径了:

VALGRIND_LIB=/home/sun/share/install/lib ./valgrind/home/sun/share/install/bin/valgrind --help

如果可以正常运行,那就设置到环境变量,只在当前终端有效,如果开启另一个终端,则需要再次设置,如果终端关闭或板子重启,同样需要再次设置:

export VALGRIND_LIB=/home/test/valgrind/lib/valgrind

 

设置后就可以直接运行了 ./valgrind/home/sun/share/install/bin/valgrind --help 可以成功运行

 

./valgrind/home/sun/share/install/bin/valgrind ls 报错

错误信息是:内部错误,valgrind 段错误退出了

来来回回折腾了好几天,交叉工具链都重新制作了,用新版本的uclibc,依然报错

替换内核版本后 依然报错

换成几个旧版本的valgrind 依然报错

最后又重新查看 valgrind 对平台的CPU架构的支持,才发现一开始就由于疏忽错过了重要信息

当前

Valgrind支持以下平台:

  • x86 / Linux:最高可包括SSSE3,但不高 - 没有SSE4,AVX,AVX2。 此目标现在处于维护模式..
  • AMD64 / Linux:包括AVX2在内。 这是主要的开发目标,并且往往得到很好的支持。
  • PPC32 / Linux,PPC64 / Linux,PPC64LE / Linux:包括Power8在内。
  • S390X / Linux:支持。
  • ARM / Linux:自ARMv7起支持。
  • ARM64 / Linux: ARMv8支持。
  • MIPS32 / Linux,MIPS64 / Linux:支持。
  • X86 / Solaris,AMD64 / Solaris,X86 / illumos,AMD64 / illumos :自Solaris 11以来受支持。
  • X86 / Darwin(10.10,10.11),AMD64 / Darwin(10.10,10.11):支持。
  • ARM / Android,ARM64 / Android,MIPS32 / Android,X86 / Android:支持。

在Linux上,您必须运行内核3.0或更高版本,以及glibc 2.5.X或更高版本在Mac OS X上,您必须运行10.9.x或更高版本。

移植计划

Valgrind 3.X拥有支持多平台的基础设施。 平台是特定的(CPU,OS)配对,例如x86 / Linux或AMD64 / Linux。

维护每个端口需要付出很多努力,比大多数其他程序要多。 Valgrind很脆弱,因为它的作用很低级。 此外,每个平台端口都有特定于CPU的代码,特定于操作系统的代码和特定于平台的代码,并且难以测试所有组合。

因此,我们只能证明支持广泛使用的平台。 与NetBSD或GCC不同,我们对Valgrind在已知领域的每个平台上工作都不感兴趣:维护负担过高。 因此,将Valgrind移植到不同的平台并不仅仅是一项技术练习:您还需要做出一个令人信服的案例,即努力是值得的,并且至少在可预见的未来,端口将得到适当的支持。

Windows不在考虑之中,因为移植到它需要进行如此多的更改,它几乎就是一个单独的项目。 (但是,Valgrind + Wine可以通过一些努力来实现。)此外,非开源操作系统很难处理; 能够看到操作系统和相关的(libc)源代码使事情变得更容易。 但是,Valgrind可以与Wine结合使用,这意味着可以在Valgrind下运行Windows程序。

此消息说明了我们的移植原理。 我们一如既往地采用灵活的方法,如果您有任何意见,我们有兴趣听取您的意见/移植需求。

我的内核是 4.4.110 支持的,但C库是uclibc valgrind不支持,所以无法运行

最后,valgrind 在 ARM Linux 下交叉编译时:

对CPU 架构、内核版本、Glibc 版本都有严格要求,大家在移植前需要到官网查看

linuxboy的RSS地址:https://www.linuxboy.net/rssFeed.aspx

本文永久更新链接地址:https://www.linuxboy.net/Linux/2018-11/155415.htm

相关内容