首页 > 代码库 > 通过valgrind 输出的偏移地址定位源码行号

通过valgrind 输出的偏移地址定位源码行号

有时用valgrind定位内存泄露问题时当内存泄露的位置在动态库(so)中时, 输出的调用栈为问号"???"并且没有指明源码的行号.即使尝试了加 -g 的编译参数并且程序退出前不执行dlclose,也无济于事.

==29941== 17 bytes in 1 blocks are definitely lost in loss record 29 of 197
==29941==    at 0x402A185: malloc (vg_replace_malloc.c:292)
==29941==    by 0x4048585: ??? (in /home/xxx/ElastosRDKforDevice/Targets/rdk/x86.gnu.linux.dbg/bin/Elastos.Runtime.so)
==29941==    by 0x40799F9: ??? (in /home/xxx/ElastosRDKforDevice/Targets/rdk/x86.gnu.linux.dbg/bin/Elastos.Runtime.so)
==29941==    by 0x407AE2A: ??? (in /home/xxx/ElastosRDKforDevice/Targets/rdk/x86.gnu.linux.dbg/bin/Elastos.Runtime.so)
==29941==    by 0x407ACC0: ??? (in /home/xxx/ElastosRDKforDevice/Targets/rdk/x86.gnu.linux.dbg/bin/Elastos.Runtime.so)
==29941==    by 0x407ACF9: ??? (in /home/xxx/ElastosRDKforDevice/Targets/rdk/x86.gnu.linux.dbg/bin/Elastos.Runtime.so)
==29941==    by 0x400ED76: call_init.part.0 (dl-init.c:78)
==29941==    by 0x400EE63: _dl_init (dl-init.c:36)
==29941==    by 0x400110E: ??? (in /lib/i386-linux-gnu/ld-2.19.so)

这种情况下通过每行的偏移地址配合addr2line也可以定位到具体的代码行:

1. 重新运行valgrind命令执行内存泄露的检查工作.

2. 查看valgrind log中的thread Id, 如上"29941"

3. 在程序退出之前 cat /proc/29941/maps 文件, 可以看到加载动态库的信息

04038000-040ab000 r-xp 00000000 08:05 6560496    /home/xxx/ElastosRDKforDevice/Targets/rdk/x86.gnu.linux.dbg/bin/Elastos.Runtime.so
040ab000-040ac000 r--p 00073000 08:05 6560496    /home/xxx/ElastosRDKforDevice/Targets/rdk/x86.gnu.linux.dbg/bin/Elastos.Runtime.so
040ac000-040ad000 rw-p 00074000 08:05 6560496    /home/xxx/ElastosRDKforDevice/Targets/rdk/x86.gnu.linux.dbg/bin/Elastos.Runtime.so
我们关心的是 r-xp 这一行, 最前边的 04038000 就是这个动态库加载的 base 地址.

4. 然后用发生内存泄露的地址0x4048585减去base地址0x4038000, 得到 0x10585 的相对偏移地址.

5. 利用addr2line工具

addr2line -e ./Elastos.Runtime.so 0x10585

得到具体源码行号:

/home/xxx/ElastosRDKforDevice/Sources/ElastosSources/Elastos/Runtime/Library/eltypes/elstring/elsharedbuf.cpp:9

打完收工.



通过valgrind 输出的偏移地址定位源码行号