在嵌入式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到服务器

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)


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在 OpenWrt 上使用 Valgrind 需要注意以下几点: 1. 安装 Valgrind 可以通过 opkg 安装 Valgrind: ``` opkg update opkg install valgrind ``` 2. 配置 Valgrind 默认情况下,Valgrind 会使用 glibc 库,而 OpenWrt 中使用的是 uClibc 库,因此需要手动配置 Valgrind。 首先,需要创建一个文件 `/etc/valgrindrc`,并添加以下内容: ``` # Valgrind configuration file for uClibc libc-libraries: /lib/libuClibc-*.so.* ``` 然后,在运行 Valgrind 时,需要指定使用该配置文件: ``` valgrind --tool=memcheck --vgdb=no --trace-children=yes --num-callers=20 --suppressions=/usr/lib/valgrind/uClibc.supp --read-var-info=yes --malloc-fill=0xFE --free-fill=0xEF --leak-check=full --show-reachable=yes --track-origins=yes --log-file=/tmp/valgrind.log --error-limit=no --undef-value-errors=no --gen-suppressions=all --fair-sched=yes --quiet --trace-children=yes --trace-children-skip=*dhclient* --trace-children-skip=*udhcpc* --trace-children-skip=*pppd* --trace-children-skip=*klogd* --trace-children-skip=*syslogd* --trace-children-skip=*hotplug2* --trace-children-skip=*ntpd* --trace-children-skip=*odhcpd* --trace-children-skip=*dnsmasq* --trace-children-skip=*hostapd* --trace-children-skip=*wpa_supplicant* --trace-children-skip=*ubusd* --trace-children-skip=*logd* --trace-children-skip=*smbd* --trace-children-skip=*nmbd* --trace-children-skip=*irqbalance* --trace-children-skip=*procd* --trace-children-skip=*crond* --trace-children-skip=*ubus* --trace-children-skip=*ubusd* --trace-children-skip=*uhttpd* --trace-children-skip=*amule* --trace-children-skip=*transmission* --trace-children-skip=*minidlna* --trace-children-skip=*mjpg_streamer* --trace-children-skip=*sshd* --trace-children-skip=*swapon* --trace-children-skip=*swapoff* --trace-children-skip=*fstab* --trace-children-skip=*mount* --trace-children-skip=*umount* --trace-children-skip=*tar* --trace-children-skip=*rsync* --trace-children-skip=*scp* --trace-children-skip=*sftp* --trace-children-skip=*ftpd* --trace-children-skip=*ftp* --trace-children-skip=*telnetd* --trace-children-skip=*ssh* --trace-children-skip=*tftp* --trace-children-skip=*httpd* --trace-children-skip=*vnstatd* --trace-children-skip=*ntfs-3g* --trace-children-skip=*samba* --trace-children-skip=*proftpd* --trace-children-skip=*lighttpd* --trace-children-skip=*php* --trace-children-skip=*mysql* --trace-children-skip=*sqlite3* --trace-children-skip=*redis* --trace-children-skip=*memcached* --trace-children-skip=*mosquitto* --trace-children-skip=*influxd* --trace-children-skip=*grafana-server* --trace-children-skip=*postgresql* --trace-children-skip=*mongodb* --trace-children-skip=*cupsd* --trace-children-skip=*dovecot* --trace-children-skip=*nginx* --trace-children-skip=*php-fpm* --trace-children-skip=*thttpd* --trace-children-skip=*dnscrypt-proxy* --trace-children-skip=*tor* --trace-children-skip=*tinyproxy* --trace-children-skip=*privoxy* --trace-children-skip=*squid* --trace-children-skip=*polipo* --trace-children-skip=*darkhttpd* --trace-children-skip=*kamailio* --trace-children-skip=*opensips* --trace-children-skip=*asterisk* --trace-children-skip=*freeswitch* --trace-children-skip=*nagios* --trace-children-skip=*nrpe* --trace-children-skip=*collectd* --trace-children-skip=*snmpd* --trace-children-skip=*openvpn* --trace-children-skip=*pptpd* --trace-children-skip=*strongswan* --trace-children-skip=*xl2tpd* --trace-children-skip=*pppoe-server* --trace-children-skip=*pppoe-relay* --trace-children-skip=*pppoe* --trace-children-skip=*ppp* --trace-children-skip=*rtorrent* --trace-children-skip=*transmission-daemon* --trace-children-skip=*darkstat* --trace-children-skip=*vnstat* --trace-children-skip=*iptraf-ng* --trace-children-skip=*tcpdump* --trace-children-skip=*wireshark* --trace-children-skip=*snort* --trace-children-skip=*sflowtool* --trace-children-skip=*sflow-rt* --trace-children-skip=*ntopng* --trace-children-skip=*openvswitch* --trace-children-skip=*kmod* --trace-children-skip=*iptables* --trace-children-skip=*ip6tables* --trace-children-skip=*ipset* --trace-children-skip=*ulogd* --trace-children-skip=*dhcp6c* --trace-children-skip=*dhcp6s* --trace-children-skip=*wide-dhcpv6* --trace-children-skip=*radvd* --trace-children-skip=*6relayd* --trace-children-skip=*odhcp6c* --trace-children-skip=*odhcpd-dhcpv6* --trace-children-skip=*ip6tables-save* --trace-children-skip=*ip6tables-restore* --trace-children-skip=*iptables-save* --trace-children-skip=*iptables-restore* --trace-children-skip=*ip6tables-restore* --trace-children-skip=*iptables-restore* --trace-children-skip=*logrotate* --trace-children-skip=*sysupgrade* --trace-children-skip=*jffs2dump* --trace-children-skip=*ubiformat* --trace-children-skip=*ubiupdatevol* --trace-children-skip=*ubiattach* --trace-children-skip=*ubidetach* --trace-children-skip=*ubimkvol* --trace-children-skip=*ubirmvol* --trace-children-skip=*ubirename* --trace-children-skip=*ubiupdatevol* --trace-children-skip=*ubiblock* --trace-children-skip=*ubinize* --trace-children-skip=*ubi* --trace-children-skip=*mtd* --trace-children-skip=*dd* --trace-children-skip=*fdisk* --trace-children-skip=*parted* --trace-children-skip=*mkfs* --trace-children-skip=*mkswap* --trace-children-skip=*mkfs.ext3* --trace-children-skip=*mkfs.ntfs* --trace-children-skip=*mkfs.vfat* --trace-children-skip=*mkfs.xfs* --trace-children-skip=*mkfs.jffs2* --trace-children-skip=*mkfs.ubifs* --trace-children-skip=*mount* --trace-children-skip=*umount* --trace-children-skip=*mount* --trace-children-skip=*umount* --trace-children-skip=*fsck* --trace-children-skip=*fsck.ext3* --trace-children-skip=*fsck.ntfs* --trace-children-skip=*fsck.vfat* --trace-children-skip=*fsck.xfs* --trace-children-skip=*fsck.jffs2* --trace-children-skip=*fsck.ubifs* --trace-children-skip=*e2label* --trace-children-skip=*ntfslabel* --trace-children-skip=*dosfslabel* --trace-children-skip=*xfs_admin* --trace-children-skip=*jffs2* --trace-children-skip=*mke2fs* --trace-children-skip=*ntfs-3g.probe* --trace-children-skip=*ntfs-3g.secaudit* --trace-children-skip=*ntfs-3g.usermap* --trace-children-skip=*ntfs-3g* --trace-children-skip=*mount.ntfs-3g* --trace-children-skip=*mount.ntfs* --trace-children-skip=*udhcpc* --trace-children-skip=*dhclient* --trace-children-skip=*dhcpd* --trace-children-skip=*dnsmasq* --trace-children-skip=*hostapd_cli* --trace-children-skip=*wpa_cli* --trace-children-skip=*wpa_supplicant* --trace-children-skip=*pppd* --trace-children-skip=*pptp* --trace-children-skip=*l2tpd* --trace-children-skip=*openconnect* --trace-children-skip=*openvpn* --trace-children-skip=*strongswan* --trace-children-skip=*xl2tpd* --trace-children-skip=*pppoe-server* --trace-children-skip=*pppoe-relay* --trace-children-skip=*pppoe* --trace-children-skip=*ppp* --trace-children-skip=*smbd* --trace-children-skip=*nmbd* --trace-children-skip=*nmblookup* --trace-children-skip=*smbclient* --trace-children-skip=*smbpasswd* --trace-children-skip=*smbstatus* --trace-children-skip=*smbtree* --trace-children-skip=*wins* --trace-children-skip=*samba-tool* --trace-children-skip=*transmission* --trace-children-skip=*transmission-daemon* --trace-children-skip=*amule* --trace-children-skip=*aria2c* --trace-children-skip=*wget* --trace-children-skip=*curl* --trace-children-skip=*ftp* --trace-children-skip=*scp* --trace-children-skip=*sftp* --trace-children-skip=*rsync* --trace-children-skip=*tar* --trace-children-skip=*tftp* --trace-children-skip=*telnet* --trace-children-skip=*ssh* --trace-children-skip=*sftp-server* --trace-children-skip=*ftp-proxy* --trace-children-skip=*proxsmtp* --trace-children-skip=*spamassassin* --trace-children-skip=*fetchmail* --trace-children-skip=*dovecot* --trace-children-skip=*postfix* --trace-children-skip=*exim* --trace-children-skip=*sendmail* --trace-children-skip=*nginx* --trace-children-skip=*apache2* --trace-children-skip=*lighttpd* --trace-children-skip=*php* --trace-children-skip=*mysql* --trace-children-skip=*postgresql* --trace-children-skip=*mosquitto* --trace-children-skip=*influxd* --trace-children-skip=*grafana-server* --trace-children-skip=*memcached* --trace-children-skip=*redis* --trace-children-skip=*mongodb* --trace-children-skip=*cupsd* --trace-children-skip=*darkhttpd* --trace-children-skip=*dnscrypt-proxy* --trace-children-skip=*tor* --trace-children-skip=*tinyproxy* --trace-children-skip=*privoxy* --trace-children-skip=*squid* --trace-children-skip=*polipo* --trace-children-skip=*kamailio* --trace-children-skip=*opensips* --trace-children-skip=*asterisk* --trace-children-skip=*freeswitch* --trace-children-skip=*nagios* --trace-children-skip=*nrpe* --trace-children-skip=*collectd* --trace-children-skip=*snmpd* --trace-children-skip=*openvswitch* --trace-children-skip=*iptables* --trace-children-skip=*ip6tables* --trace-children-skip=*ipset* --trace-children-skip=*ulogd* --trace-children-skip=*dhcp6c* --trace-children-skip=*dhcp6s* --trace-children-skip=*wide-dhcpv6* --trace-children-skip=*radvd* --trace-children-skip=*6relayd* --trace-children-skip=*odhcp6c* --trace-children-skip=*odhcpd-dhcpv6* --trace-children-skip=*ip6tables-save* --trace-children-skip=*ip6tables-restore* --trace-children-skip=*iptables-save* --trace-children-skip=*iptables-restore* --trace-children-skip=*ip6tables-restore* --trace-children-skip=*iptables-restore* --trace-children-skip=*logrotate* --trace-children-skip=*sysupgrade* --trace-children-skip=*opkg* ``` 这里的参数根据需求来调整。 3. 运行 Valgrind 使用 `valgrind` 命令即可运行 Valgrind,例如: ``` valgrind --tool=memcheck --leak-check=full myprogram arg1 arg2 ``` 这里的 `myprogram` 是需要测试的程序,`arg1`、`arg2` 是该程序的参数。 注意:Valgrind 会对程序的运行速度有一定的影响,因此在测试时需要对程序进行压力测试,以确保测试结果的准确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值