安装环境:
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到服务器
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)