how to use valgrind with remote gdb on openwrt
FAQ
- enable PRELOAD in uClibc
- diff --git a/toolchain/uClibc/config-0.9.33.2/common b/toolchain/uClibc/config-0.9.33.2/common
- index 3b3c4dd..19547cc 100644
- --- a/toolchain/uClibc/config-0.9.33.2/common
- +++ b/toolchain/uClibc/config-0.9.33.2/common
- @@ -36,7 +36,7 @@ LDSO_LDD_SUPPORT=y
- # LDSO_NO_CLEANUP is not set
- # LDSO_PRELINK_SUPPORT is not set
- # LDSO_PRELOAD_FILE_SUPPORT is not set
- -# LDSO_PRELOAD_ENV_SUPPORT is not set
- +LDSO_PRELOAD_ENV_SUPPORT=y
- LDSO_RUNPATH=y
- # LDSO_SEARCH_INTERP_PATH is not set
- # LDSO_STANDALONE_SUPPORT is not set
- overwrite unstripped uClibc and valgrind libs
- /home/llwang/repos/osdk_repos/staging_dir/target-mips_r2_uClibc-0.9.33.2/root-ar71xx/lib/libuClibc-0.9.33.2.so
- /home/llwang/repos/osdk_repos/staging_dir/target-mips_r2_uClibc-0.9.33.2/root-ar71xx/usr/lib/libuClibc++-0.2.4.so
- /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
- /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是一个动态分析工具框架,其中包含如下模块:
- memcheck - 一个内存错误探测器,
- cachegrind - 一个缓存和分支预测分析器
- callgrind - 一个调用图产生缓存分析器
- helgrind - 一个线程那个错误探测器
- DRD - 另一个线程错误探测器
- Massif - 堆分析器
- DHAT - 另一个堆分析器
- SGcheck - 探测栈和全局数组超出
- BBV - SimPoint basic block vector生成器
- vgdb - valgrind的gdb支持
Openwrt上的Valgrind
启用并编译valgrind组件
make menuconfig && make package/valgrind/compile V=s
- CONFIG_PACKAGE_valgrind=m
- CONFIG_PACKAGE_valgrind-cachegrind=m
- CONFIG_PACKAGE_valgrind-callgrind=m
- CONFIG_PACKAGE_valgrind-drd=m
- CONFIG_PACKAGE_valgrind-helgrind=m
- CONFIG_PACKAGE_valgrind-massif=m
- CONFIG_PACKAGE_valgrind-vgdb=m
生成的包在这里:
- llwang@VM2~/repos/osdk_repos $ ls -l $PWD/bin/ar71xx/packages/valgrind*
- -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
- -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
- -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
- -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
- -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
- -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
- -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上
- $ opkg install valgrind*.ipk
运行valgrind在Openwrt Box上
关于vgdb的选项
- llwang@VM2~/repos/osdk_repos $ valgrind --help | grep vgdb
- --vgdb=no|yes|full activate gdbserver? [yes]
- --vgdb-error=<number> invoke gdbserver after <number> errors [999999999]
- to get started quickly, use --vgdb-error=0
- --vgdb-stop-at=event1,event2,... invoke gdbserver for given events [none]
- --vgdb-poll=<number> gdbserver poll max every <number> basic blocks [5000]
- --vgdb-shadow-registers=no|yes let gdb see the shadow registers [no]
- --vgdb-prefix=<prefix> prefix for vgdb FIFOs [/tmp/vgdb-pipe]
用法
- $ 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监听指定端口
- $ vgdb --port=2345
生成supperssions配置文件
- $ 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
- sed -i -e '/==[0-9]*==/d' -e '/--[0-9]*--/d'
supperission files
- {
- <insert_a_suppression_name_here>
- Memcheck:Param
- socketcall.sendto(msg)
- fun:__sys_sendto
- fun:sendto
- }
- {
- <insert_a_suppression_name_here>
- Memcheck:Param
- socketcall.sendto(msg)
- fun:__sys_sendto
- fun:sendto
- }
- {
- <insert_a_suppression_name_here>
- Memcheck:Leak
- fun:calloc
- obj:/lib/ld-uClibc-0.9.33.2.so
- }
- {
- <insert_a_suppression_name_here>
- Memcheck:Cond
- fun:_uintmaxtostr
- fun:_vfprintf_internal
- }
- {
- <insert_a_suppression_name_here>
- Memcheck:Jump
- obj:*
- fun:_vgnU_freeres
- obj:/lib/libpthread-0.9.33.2.so
- }
- {
- <insert_a_suppression_name_here>
- Memcheck:Addr4
- obj:/lib/libuci.so
- obj:/lib/libuci.so
- }
- {
- <insert_a_suppression_name_here>
- Memcheck:Free
- fun:free
- obj:/lib/libuci.so
- }
- {
- <insert_a_suppression_name_here>
- Memcheck:Jump
- obj:*
- fun:_vgnU_freeres
- obj:/lib/libuci.so
- }
-
-
Host PC上的gdb
当valgrind检测到错误后会触发gdb的trap停止下来,以便查看错误调用信息
- $ mips-openwrt-linux-gdb root-ar71xx/usr/sbin/ok_capwapc
- gdb > target remote 172.16.0.156:2345
- gdb > monitor leak_check full reachable any
Reference
nicephil@gmail.com 2017-4-6