在嵌入式uClibc上移植valgrind

安装环境:

Linux ubuntu-hz 4.2.0-27-generic#32~14.04.1-Ubuntu SMP Fri Jan 22 15:32:26 UTC 2016 x86_64 x86_64 x86_64GNU/Linux

交叉编译器:arm-hisiv300-linux


移植原因:

valgrind监控的执行文件要求:动态编译,动态库没有strip过。但是厂家提供的arm-hisiv300-linux的动态库都是strip掉的,所以用valgrind跑出来的结果是不正确的,没有检查出泄露、越界等情况。因此下载一个和厂家版本一样的uClibc进行配置、编译,替换掉现有的动态库,然后在动态编译可执行文件,就可以用valgrind监控。


步骤如下:

1、安装现有厂家的交叉编译器

拷贝 arm-hisiv300-linux.tar.bz2和cross.v300.install到服务器

扫描二维码关注公众号,回复: 2556213 查看本文章

cross.v300.install修改为安装目录:

TOP_DIR=/home/he_liangbin/bin

./cross.v300.install 安装交叉编译器

最后跳出选择,直接abort即可


2、编译uClibc

https://www.uclibc.org/下载交叉编译器一样的版本:0.9.33.2

解压:

tar xf uClibc-0.9.33.2.tar.xz 解压版本

进入根目录,make menuconfig,进行配置:

diff uClibc-0.9.33.2/.config  uClibc-0.9.33.2_mm/.config

4c4
< # Tue Oct 31 10:28:06 2017
---
> # Fri Oct 27 20:21:16 2017
7c7
< # TARGET_arm is not set
---
> TARGET_arm=y
30c30
< TARGET_x86_64=y
---
> # TARGET_x86_64 is not set
36c36
< TARGET_ARCH="x86_64"
---
> TARGET_ARCH="arm"
37a38,40
> CONFIG_ARM_EABI=y
> # COMPILE_IN_THUMB_MODE is not set
> # USE_BX is not set
42a46
> ARCH_ANY_ENDIAN=y
44,47c48,49

< #
< # Using Little Endian
< #
---
> # ARCH_WANTS_BIG_ENDIAN is not set
> ARCH_WANTS_LITTLE_ENDIAN=y
52c54
< # DO_C99_MATH is not set
---
> DO_C99_MATH=y
55c57
< KERNEL_HEADERS="/usr/include"
---
> KERNEL_HEADERS="/home/he_liangbin/bin/arm-hisiv300-linux/target/usr/include"(1)
78c80
< HAS_NO_THREADS=y
---
> # HAS_NO_THREADS is not set
81c83,86
< # UCLIBC_HAS_THREADS_NATIVE is not set
---
> UCLIBC_HAS_THREADS_NATIVE=y
> UCLIBC_HAS_THREADS=y
> UCLIBC_HAS_TLS=y
> # PTHREADS_DEBUG_SUPPORT is not set
90c95
< # UCLIBC_SUSV3_LEGACY is not set
---
> UCLIBC_SUSV3_LEGACY=y
92c97
< # UCLIBC_SUSV4_LEGACY is not set
---
> UCLIBC_SUSV4_LEGACY=y
140,142c145,150
< # UCLIBC_HAS_IPV6 is not set
< # UCLIBC_HAS_RPC is not set
< # UCLIBC_USE_NETLINK is not set
---
> UCLIBC_HAS_IPV6=y
> UCLIBC_HAS_RPC=y
> UCLIBC_HAS_FULL_RPC=y
> UCLIBC_HAS_REENTRANT_RPC=y
> UCLIBC_USE_NETLINK=y
> UCLIBC_SUPPORT_AI_ADDRCONFIG=y
146,148c154,156
< # UCLIBC_HAS_RESOLVER_SUPPORT is not set
< # UCLIBC_HAS_LIBRESOLV_STUB is not set
< # UCLIBC_HAS_LIBNSL_STUB is not set
---
> UCLIBC_HAS_RESOLVER_SUPPORT=y
> UCLIBC_HAS_LIBRESOLV_STUB=y
> UCLIBC_HAS_LIBNSL_STUB=y
160c168
< # UCLIBC_HAS_WCHAR is not set
---
> UCLIBC_HAS_WCHAR=y
164d171
< # USE_OLD_VFPRINTF is not set
190a198
> UCLIBC_HAS_STDIO_FUTEXES=y
201a210
> # UCLIBC_HAS_FTW is not set
210,211c219,220
< RUNTIME_PREFIX="/usr/$(TARGET_ARCH)-linux-uclibc/"
< DEVEL_PREFIX="/usr/$(TARGET_ARCH)-linux-uclibc/usr/"
---
> RUNTIME_PREFIX="/home/he_liangbin/cross_compile/tool-chain"(2)
> DEVEL_PREFIX="/home/he_liangbin/cross_compile/tool-chain/usr"
217a227
> # UCLIBC_BUILD_PIE is not set
219c229,234
< # UCLIBC_HAS_SSP is not set
---
> UCLIBC_HAS_SSP=y
> # UCLIBC_HAS_SSP_COMPAT is not set
> # SSP_QUICK_CANARY is not set
> PROPOLICE_BLOCK_ABRT=y
> # PROPOLICE_BLOCK_SEGV is not set
> # UCLIBC_BUILD_SSP is not set
227c242
< CROSS_COMPILER_PREFIX=""
---
> CROSS_COMPILER_PREFIX="arm-hisiv300-linux-"(3)
230c245
< DOSTRIP=y
---
> # DOSTRIP is not set(4)

红色(1)内核头文件安装路径

红色(2)uClibc安装路径

红色(3)交叉编译

红色(4)库不要strip掉


make

make install

cp ~/cross_compile/tool-chain/lib/*~/bin/arm-hisiv300-linux/target/lib/

cp ~/cross_compile/tool-chain/usr/*~/bin/arm-hisiv300-linux/target/usr/ -rf

以上是替换原来的uClibc库

makePREFIX=/home/he_liangbin/bin/arm-hisiv300-linux/target install

PREFIX为交叉编译器安装路径,必须要否则动态编译不过,见问题2


3、编译valgrind

tar xf valgrind-3.13.0.tar.bz2

修改configure 5629代码:armv7*) -> armv7* | arm)

make distclean

./configure --host=arm-hisiv300-linuxCC=arm-hisiv300-linux-gcc CPP=arm-hisiv300-linux-cpp CXX=arm-hisiv300-linux-g++ --prefix=/home/he_liangbin/valgrind

make

make install

注意红色部分:挂载到设备上运行valgrind时也必须要在这个路径。


4、测试

源码:

  1#include <stdlib.h>

  2#include <malloc.h>

  3#include <string.h>

  4

  5void test()

  6 {

 7     int *ptr =malloc(sizeof(int)*10);

  8

 9     ptr = malloc(10);

 10

 11    ptr[11] = 7; // 内存越界 

 12    memcpy(ptr +1, ptr, 11); // 踩内存 

 13

 14

 15    free(ptr);

 16    free(ptr);// 重复释放 

 17

 18    int *p1;

 19    *p1 = 1; // 非法指针 

 20    printf("%d\n", ptr[8]);

 21 }

 22

 23int main(void)

 24 {

 25    test();

 26    return 0;

 27 }

 28

测试结果:

/home/he_liangbin/valgrind/bin # ./valgrind/home/memcheck_test

==954== Memcheck, a memory error detector

==954== Copyright (C) 2002-2017, and GNUGPL'd, by Julian Seward et al.

==954== Using Valgrind-3.13.0 and LibVEX;rerun with -h for copyright info

==954== Command: /home/memcheck_test

==954==

==954== Invalid read of size 4

==954==   at 0x400580C: _dl_get_ready_to_run (in /lib/ld-uClibc.so.0)

==954== Address 0xbdf99a24 is on thread 1's stack

==954== 20 bytes below stack pointer

==954==

==954== Invalid read of size 4

==954==   at 0x487641C: __uClibc_main (in /lib/libc.so.0)

==954== Address 0xbdf99bec is on thread 1's stack

==954== 20 bytes below stack pointer

==954==

==954== Invalid write of size 4

==954==   at 0x858C: test (memcheck_test.c:11)

==954==   by 0x85F3: main (memcheck_test.c:25)

==954== Address 0x488a0ac is 20 bytes before an unallocated block of size4,194,088 in arena "client"

==954==

==954== Source and destination overlap inmemcpy(0x488a084, 0x488a080, 11)

==954==   at 0x4821FD8: memcpy (vg_replace_strmem.c:1023)

==954==   by 0x85A7: test (memcheck_test.c:12)

==954==   by 0x85F3: main (memcheck_test.c:25)

==954==

==954== Invalid read of size 1

==954==   at 0x4822150: memcpy (vg_replace_strmem.c:1023)

==954==   by 0x85A7: test (memcheck_test.c:12)

==954==   by 0x85F3: main (memcheck_test.c:25)

==954== Address 0x488a08a is 0 bytes after a block of size 10 alloc'd

==954==   at 0x481C6E0: malloc (vg_replace_malloc.c:299)

==954==   by 0x8577: test (memcheck_test.c:9)

==954==   by 0x85F3: main (memcheck_test.c:25)

==954==

==954== Invalid write of size 1

==954==   at 0x482215C: memcpy (vg_replace_strmem.c:1023)

==954==   by 0x85A7: test (memcheck_test.c:12)

==954==   by 0x85F3: main (memcheck_test.c:25)

==954== Address 0x488a08e is 4 bytes after a block of size 10 alloc'd

==954==   at 0x481C6E0: malloc (vg_replace_malloc.c:299)

==954==   by 0x8577: test (memcheck_test.c:9)

==954==   by 0x85F3: main (memcheck_test.c:25)

==954==

==954== Invalid write of size 4

==954==   at 0x4822188: memcpy (vg_replace_strmem.c:1023)

==954==   by 0x85A7: test (memcheck_test.c:12)

==954==   by 0x85F3: main (memcheck_test.c:25)

==954== Address 0x488a088 is 8 bytes inside a block of size 10 alloc'd

==954==   at 0x481C6E0: malloc (vg_replace_malloc.c:299)

==954==   by 0x8577: test (memcheck_test.c:9)

==954==   by 0x85F3: main (memcheck_test.c:25)

==954==

==954== Invalid free() / delete / delete[]/ realloc()

==954==   at 0x481DD0C: free (vg_replace_malloc.c:530)

==954==   by 0x85B7: test (memcheck_test.c:16)

==954==   by 0x85F3: main (memcheck_test.c:25)

==954== Address 0x488a080 is 0 bytes inside a block of size 10 free'd

==954==   at 0x481DD0C: free (vg_replace_malloc.c:530)

==954==   by 0x85AF: test (memcheck_test.c:15)

==954==   by 0x85F3: main (memcheck_test.c:25)

==954== Block was alloc'd at

==954==   at 0x481C6E0: malloc (vg_replace_malloc.c:299)

==954==   by 0x8577: test (memcheck_test.c:9)

==954==   by 0x85F3: main (memcheck_test.c:25)

==954==

==954== Use of uninitialised value of size4

==954==   at 0x85C0: test (memcheck_test.c:19)

==954==   by 0x85F3: main (memcheck_test.c:25)

==954==

==954== Invalid read of size 4

==954==   at 0x85CC: test (memcheck_test.c:20)

==954==   by 0x85F3: main (memcheck_test.c:25)

==954== Address 0x488a0a0 is 16 bytes after a block of size 16 in arena"client"

==954==

0

==954== Invalid read of size 4

==954==   at 0x4876250: __uClibc_fini (in /lib/libc.so.0)

==954== Address 0xbdf99bcc is on thread 1's stack

==954== 20 bytes below stack pointer

==954==

==954== Invalid read of size 4

==954==   at 0x4000E9C: ??? (in /lib/ld-uClibc.so.0)

==954== Address 0xbdf99bbc is on thread 1's stack

==954== 20 bytes below stack pointer

==954==

/home/memcheck_test: can't resolve symbol'__libc_freeres'

==954==

==954== HEAP SUMMARY:

==954==    in use at exit: 40 bytes in 1 blocks

==954==  total heap usage: 2 allocs, 2 frees, 50 bytes allocated

==954==

==954== LEAK SUMMARY:

==954==   definitely lost: 40 bytes in 1 blocks

==954==   indirectly lost: 0 bytes in 0 blocks

==954==     possibly lost: 0 bytes in 0 blocks

==954==   still reachable: 0 bytes in 0 blocks

==954==         suppressed: 0 bytes in 0 blocks

==954== Rerun with --leak-check=full to seedetails of leaked memory

==954==

==954== For counts of detected andsuppressed errors, rerun with: -v

==954== Use --track-origins=yes to seewhere uninitialised values come from

==954== ERROR SUMMARY: 58 errors from 12contexts (suppressed: 0 from 0)


猜你喜欢

转载自blog.csdn.net/heliangbin87/article/details/78399549