首页 > 技术文章 > how to use valgrind with remote gdb on openwrt

nicephil 2017-04-06 17:09 原文

how to use valgrind with remote gdb on openwrt

FAQ

  1. enable PRELOAD in uClibc
  1. diff --git a/toolchain/uClibc/config-0.9.33.2/common b/toolchain/uClibc/config-0.9.33.2/common 
  2. index 3b3c4dd..19547cc 100644 
  3. --- a/toolchain/uClibc/config-0.9.33.2/common 
  4. +++ b/toolchain/uClibc/config-0.9.33.2/common 
  5. @@ -36,7 +36,7 @@ LDSO_LDD_SUPPORT=y 
  6. # LDSO_NO_CLEANUP is not set 
  7. # LDSO_PRELINK_SUPPORT is not set 
  8. # LDSO_PRELOAD_FILE_SUPPORT is not set 
  9. -# LDSO_PRELOAD_ENV_SUPPORT is not set 
  10. +LDSO_PRELOAD_ENV_SUPPORT=y 
  11. LDSO_RUNPATH=y 
  12. # LDSO_SEARCH_INTERP_PATH is not set 
  13. # LDSO_STANDALONE_SUPPORT is not set 
  1. overwrite unstripped uClibc and valgrind libs
  1. /home/llwang/repos/osdk_repos/staging_dir/target-mips_r2_uClibc-0.9.33.2/root-ar71xx/lib/libuClibc-0.9.33.2.so 
  2. /home/llwang/repos/osdk_repos/staging_dir/target-mips_r2_uClibc-0.9.33.2/root-ar71xx/usr/lib/libuClibc++-0.2.4.so 
  3. /home/llwang/repos/osdk_repos/staging_dir/target-mips_r2_uClibc-0.9.33.2/root-ar71xx/usr/lib/valgrind/vgpreload_core-mips32-linux.so 
  4. /home/llwang/repos/osdk_repos/staging_dir/target-mips_r2_uClibc-0.9.33.2/root-ar71xx/usr/lib/valgrind/vgpreload_memcheck-mips32-linux.so 

Background

valgrind是一个动态分析工具框架,其中包含如下模块:

  1. memcheck - 一个内存错误探测器,
  2. cachegrind - 一个缓存和分支预测分析器
  3. callgrind - 一个调用图产生缓存分析器
  4. helgrind - 一个线程那个错误探测器
  5. DRD - 另一个线程错误探测器
  6. Massif - 堆分析器
  7. DHAT - 另一个堆分析器
  8. SGcheck - 探测栈和全局数组超出
  9. BBV - SimPoint basic block vector生成器
  10. vgdb - valgrind的gdb支持

Openwrt上的Valgrind

启用并编译valgrind组件

make menuconfig && make package/valgrind/compile V=s

  1. CONFIG_PACKAGE_valgrind=m 
  2. CONFIG_PACKAGE_valgrind-cachegrind=m 
  3. CONFIG_PACKAGE_valgrind-callgrind=m 
  4. CONFIG_PACKAGE_valgrind-drd=m 
  5. CONFIG_PACKAGE_valgrind-helgrind=m 
  6. CONFIG_PACKAGE_valgrind-massif=m 
  7. CONFIG_PACKAGE_valgrind-vgdb=m 

生成的包在这里:

  1. llwang@VM2~/repos/osdk_repos $ ls -l $PWD/bin/ar71xx/packages/valgrind* 
  2. -rw-r--r-- 1 llwang adm 2.0M Mar 23 12:37 /home/llwang/repos/osdk_repos/bin/ar71xx/packages/valgrind_3.8.0-1_ar71xx.ipk 
  3. -rw-r--r-- 1 llwang adm 1004K Mar 23 12:37 /home/llwang/repos/osdk_repos/bin/ar71xx/packages/valgrind-cachegrind_3.8.0-1_ar71xx.ipk 
  4. -rw-r--r-- 1 llwang adm 1.1M Mar 23 12:37 /home/llwang/repos/osdk_repos/bin/ar71xx/packages/valgrind-callgrind_3.8.0-1_ar71xx.ipk 
  5. -rw-r--r-- 1 llwang adm 1019K Mar 23 12:37 /home/llwang/repos/osdk_repos/bin/ar71xx/packages/valgrind-drd_3.8.0-1_ar71xx.ipk 
  6. -rw-r--r-- 1 llwang adm 1.1M Mar 23 12:38 /home/llwang/repos/osdk_repos/bin/ar71xx/packages/valgrind-helgrind_3.8.0-1_ar71xx.ipk 
  7. -rw-r--r-- 1 llwang adm 993K Mar 23 12:38 /home/llwang/repos/osdk_repos/bin/ar71xx/packages/valgrind-massif_3.8.0-1_ar71xx.ipk 
  8. -rw-r--r-- 1 llwang adm 15K Apr 6 14:54 /home/llwang/repos/osdk_repos/bin/ar71xx/packages/valgrind-vgdb_3.8.0-1_ar71xx.ipk 

安装到Openwrt Box上

  1. $ opkg install valgrind*.ipk 

运行valgrind在Openwrt Box上

关于vgdb的选项

  1. llwang@VM2~/repos/osdk_repos $ valgrind --help | grep vgdb 
  2. --vgdb=no|yes|full activate gdbserver? [yes] 
  3. --vgdb-error=<number> invoke gdbserver after <number> errors [999999999
  4. to get started quickly, use --vgdb-error=0 
  5. --vgdb-stop-at=event1,event2,... invoke gdbserver for given events [none] 
  6. --vgdb-poll=<number> gdbserver poll max every <number> basic blocks [5000]  
  7. --vgdb-shadow-registers=no|yes let gdb see the shadow registers [no] 
  8. --vgdb-prefix=<prefix> prefix for vgdb FIFOs [/tmp/vgdb-pipe] 

用法

  1. $ ulimit -p unlimited;ulimit -s 16384;valgrind --tool=memcheck --leak-check=full --suppressions=/tmp/file.supp --vgdb-error=0 --vgdb=full --log-file=/tmp/valgrind.log /usr/sbin/ok_capwapc 

开启另外一个shell,打开vgdg监听指定端口

  1. $ vgdb --port=2345 

生成supperssions配置文件

  1. $ ulimit -p unlimited;ulimit -s 16384;valgrind --tool=memcheck --leak-check=full --error-limit=no --gen-suppressions=all --log-file=/tmp/valgrind.log /usr/sbin/ok_capwapc 
  2. sed -i -e '/==[0-9]*==/d' -e '/--[0-9]*--/d' 

supperission files


  1. <insert_a_suppression_name_here> 
  2. Memcheck:Param 
  3. socketcall.sendto(msg) 
  4. fun:__sys_sendto 
  5. fun:sendto 


  6. <insert_a_suppression_name_here> 
  7. Memcheck:Param 
  8. socketcall.sendto(msg) 
  9. fun:__sys_sendto 
  10. fun:sendto 


  11. <insert_a_suppression_name_here> 
  12. Memcheck:Leak 
  13. fun:calloc 
  14. obj:/lib/ld-uClibc-0.9.33.2.so 


  15. <insert_a_suppression_name_here> 
  16. Memcheck:Cond 
  17. fun:_uintmaxtostr 
  18. fun:_vfprintf_internal 


  19. <insert_a_suppression_name_here> 
  20. Memcheck:Jump 
  21. obj:* 
  22. fun:_vgnU_freeres 
  23. obj:/lib/libpthread-0.9.33.2.so 


  24. <insert_a_suppression_name_here> 
  25. Memcheck:Addr4 
  26. obj:/lib/libuci.so 
  27. obj:/lib/libuci.so 


  28. <insert_a_suppression_name_here> 
  29. Memcheck:Free 
  30. fun:free 
  31. obj:/lib/libuci.so 


  32. <insert_a_suppression_name_here> 
  33. Memcheck:Jump 
  34. obj:* 
  35. fun:_vgnU_freeres 
  36. obj:/lib/libuci.so 

  37.  
  38.  

Host PC上的gdb

当valgrind检测到错误后会触发gdb的trap停止下来,以便查看错误调用信息

  1. $ mips-openwrt-linux-gdb root-ar71xx/usr/sbin/ok_capwapc 
  2. gdb > target remote 172.16.0.156:2345 
  3. gdb > monitor leak_check full reachable any 

Reference

valgrind manual


nicephil@gmail.com 2017-4-6

推荐阅读