Ubuntu上AOSP环境下交叉编译32/64位valgrind

本农目前在搞安卓平台C++进程开发,最近线上报故障,我们的进程启动时崩溃,错误以前从未见过,
Fatal signal 11 (SIGSEGV), code 1, fault addr 0x6 in tid 223(HandlingMessageXXXX)
这个HandlingMessageXXXX是我们一个线程,问题是这个线程语句看不出什么问题。我们想复现这个故障,但是测了整整一天都没有复现,我想可能崩溃点并不在这个线程里,但是在哪呢?我们这个进程有效代码7-8w行,挨个找无异于大海捞针,所以我想借助内存检测工具来找内存泄漏/溢出点。最终找到了valgrind这个工具,我在ubuntu下很轻松就编译成功,但最终目标是要在安卓设备上使用,所以,就需要交叉编译。

32/64位valgrind程序,已编译完成,嫌配置过程麻烦的,可以直接下载使用
32/64位valgrind程序下载https://download.csdn.net/download/oqqsoap1234567/14032595

下面开始配置过程。

(一)设置 NDK 路径
直接在命令行敲,(替换为你开发主机上的实际路径)。敲完注意再echo下,检查是否设置正确。

export NDKROOT=/home/myname/AOSP_Code/prebuilts
echo $NDKROOT

我使用的是AOSP环境,ndk直接就包含在prebuilts里面了。
在这里插入图片描述

注意啊,所有的命令都要在解压后的valgrind根目录下敲,否则,环境变量设置无效,没法编译
可以看到,我使用的版本是3.16.1
在这里插入图片描述

(二)设置硬件型号
继续敲,我就不上图了, 我设置了下面的类型,实际应用中可以和具体的目标设备关联起来。

export HWKIND=generic

(三)设置工具链路径
注意:valgrind源码可以编译成32/64位,分别用于检测32/64位程序,需要AR,LD,CC3个工具,32/64位工具所对应的工具名称路径各不相同,注意不要搞错了,比如下面这种报错,结合实际情况和网上说法,总结了3种可能性
1.系统找不到memcheck路径,这是由于–prefix指定路径和安卓设备路径不同,见步骤”(四)配置( configure )“
2.缺少./autogen.sh(我没遇到这种情况)
3.待检测程序是64位的,而编译的valgrind是32位的,因此导致 valgrind运行失败

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

如果你不确定待检测程序是32还是64位,可以用file命令检测,例如:下面test程序就是64位,所以我们要选择64位工具链

file ~/test/Mutex/test
/home/myname/test/Mutex/test: ELF 64-bit LSB  executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=e8789251befb8892fec8a05639ef31ef11e37863, not stripped

若不知道具体路径,所以根据名称使用find命令去查找。
以下为32位工具名称

arm-linux-androideabi-ar
arm-linux-androideabi-ld
arm-linux-androideabi-gcc

以下为64位工具名称

aarch64-linux-android-ar
aarch64-linux-android-ld.bfd
aarch64-linux-android-gcc

以下为找到的32位工具路径

./gcc/linux-x86/arm/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ar
./gcc/linux-x86/arm/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld
./gcc/linux-x86/arm/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-gcc

Ubuntu上AOSP环境下交叉编译32/64位valgrind_第1张图片

找到编译链接工具路径后,进行设置,以下为32位工具链设置。

export AR=$NDKROOT/gcc/linux-x86/arm/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ar
export LD=$NDKROOT/gcc/linux-x86/arm/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld
export CC=$NDKROOT/gcc/linux-x86/arm/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-gcc

以下为64位工具链设置

export AR=$NDKROOT/gcc/linux-x86/aarch64/aarch64-linux-android-4.8/bin/aarch64-linux-android-ar
export LD=$NDKROOT/gcc/linux-x86/aarch64/aarch64-linux-android-4.8/bin/aarch64-linux-android-ld.bfd
export CC=$NDKROOT/gcc/linux-x86/aarch64/aarch64-linux-android-4.8/bin/aarch64-linux-android-gcc

(四)配置( configure )
需要配置以下3个环境变量
CPPFLAGS
CFLAGS
LIBS
这里要注意下ndk路径,大家可以看下ndk目录结构。
Ubuntu上AOSP环境下交叉编译32/64位valgrind_第2张图片

继续敲,以下为32位配置路径

export CPPFLAGS="--sysroot=$NDKROOT/ndk/9/platforms/android-14/arch-arm -DANDROID_HARDWARE_$HWKIND"
export CFLAGS="--sysroot=$NDKROOT/ndk/9/platforms/android-14/arch-arm"
export LIBS="-L$NDKROOT/ndk/9/platforms/android-14/arch-arm/usr/lib"

在这里插入图片描述
以下为64位配置路径

export CPPFLAGS="--sysroot=$NDKROOT/ndk/9/platforms/android-21/arch-arm64 -DANDROID_HARDWARE_$HWKIND"
export CFLAGS="--sysroot=$NDKROOT/ndk/9/platforms/android-21/arch-arm64"
export LIBS="-L$NDKROOT/ndk/9/platforms/android-21/arch-arm64/usr/lib"

进行32位程序configure
运行valgrind目录下的configure命令

./configure --prefix=/data/local/Inst --host=armv7-unknown-linux \
--target=arm-linux-androideabi  --with-tmpdir=/sdcard

注意,以下为程序安装的路径(make install),要使程序正常运行,有以下2种方法:

--prefix=/data/local/Inst 

1.copy到安卓设备上要与此路径完全相同
2.配置lib环境变量,导出VALGRIND_LIB路径,用法如下(假设valgrind已经被安装到/home/test/valgrind目录),这样允许copy到安卓设备路径和–prefix指定路径不同,但是每次重启设备都需要配置一次,比较麻烦:

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

否则执行会报错,错误信息见步骤”(三)设置工具链路径“

进行64位程序configure

./configure --prefix=/data/local/Inst --host=aarch64-linux \
--enable-only64bit  --with-tmpdir=/sdcard

报错如下:

configure: error: C compiler cannot create executables
See `config.log' for more details.

进入config.log查看

vi config.log
aarch64-linux-android-gcc: error: unrecognized command line option '-V'
aarch64-linux-android-gcc: fatal error: no input files
compilation terminated.

基本可以确定工具链配错导致,就是CPPFLAGS,CFLAGS,LIBS这3个环境变量配置路径不对,用echo重新检查一遍

出现如下提示,则说明交叉编译环境配置成功

 		 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: android
      Primary -DVGPV string: -DVGPV_arm_linux_android=1
         Default supp files: xfree-3.supp xfree-4.supp bionic.supp

64位是这样的

         Maximum build arch: arm64
         Primary build arch: arm64
       Secondary build arch: 
                   Build OS: linux
     Link Time Optimisation: no
       Primary build target: ARM64_LINUX
     Secondary build target: 
           Platform variant: android
      Primary -DVGPV string: -DVGPV_arm64_linux_android=1
         Default supp files: xfree-3.supp xfree-4.supp bionic.supp

注意,Platform variant一定要是android,如果是vanilla,说明环境没配好,仍然是ubuntu的编译工具,需要重新检查路径。

Platform variant: vanilla

(五)编译安装( make )
敲2个命令

make
make install

最终生成的程序会copy到/data/local/Inst目录中,注意是否有权限,无权限会导致copy失败。
至此,交叉编译完成。

(六)安卓设备测试( test )
将valgrind程序及依赖库拷贝至安卓设备上,分别在/data/local/Inst下的bin和lib/valgrind目录里,共计5个文件
default.supp
memcheck-arm-linux
valgrind
vgpreload_core-arm-linux.so
vgpreload_memcheck-arm-linux.so

进入安卓设备的shell环境,设置环境变量VALGRIND_LIB为上面文件的拷贝目录,以便valgrind能够找到相关的库和可执行文件(实际上这一步骤我没做,因为我的–prefix路径和copy到安卓设备路径相同)。

export VALGRIND_LIB="/data/lib"

The end, Run

/data/lib/valgrind --leak-check=full --track-origins=yes --log-file=leak.log
 /data/MyNativeProgram

我参考了以下几位Up的博客,在他们的基础上结合自己实际环境修改了一些内容
感谢!

参考文献:
32bit工具链配置https://blog.csdn.net/loushuai/article/details/51745473
64bit工具链配置https://blog.csdn.net/m0_37874806/article/details/105590314
缺少./autogen.sh导致failed to start tool 'memcheck’https://blog.csdn.net/gllg1314/article/details/78772123
32/64位版本不匹配导致failed to start tool 'memcheck’https://blog.csdn.net/yasi_xi/article/details/7594517
valgrind运行参数配置https://blog.csdn.net/foruok/article/details/20701991

你可能感兴趣的:(C/C++,valgrind,AOSP,linux,c++,ubuntu)