mips平台运行valgrind无法统计到内存泄漏

目录

前言:

问题分析过程:

解决方案:

说明:


前言:

mips的板子上,运行了linux系统和应用程序(本公司业务程序),经过长时间观察,发现应用程序存在内存泄漏的情况,为了高效的分析出原因,交叉编译了valgrind到mips平台。

使用mips工具链,交叉编译倒是没有太大的问题,无非就是浮点运算部分在编译时,提示寄存器未定义,编译不通过。解决方法是将valgrind的那部分浮点运算的寄存器代码注释掉就行了,就可以编译通过了。

严重的问题出现在运行valgrind统计内存泄漏的时候,valgrind可以运行起来,但是无法统计到内存泄漏,“ctrl + c”将程序关闭后,输出显示没有任何可能的泄漏,这是不符合常识的,经过2天的折腾,分析了它产生的原因,暂时通过野路子解决了这个问题,以下是解决问题的过程和思路,仅供参考。

问题分析过程:

1.首先是百度,biying,overflow各种搜索,但是仍然找不到特别有效的解决问题的方法,倒是看到了在2014年就有人问过一样的问题,有人跟帖,但是无人给出解决方案。

2.在valgrind官网的buglist里面找到了类似的问题,分析原因大概就是malloc/free的调用,需要链接动态库,如果使用了其他tcmalloc或者jemalloc动态库替换了系统原生库的话,需要通过命令行指定,在valgrind源码目录下也有同样的描述,如下。

324525 – valgrind can not detect any leak (kde.org)

mips平台运行valgrind无法统计到内存泄漏_第1张图片

3.我们的程序没有使用静态库进行链接,也没有使用tcmalloc和jemalloc,但是根据这个思路来推算,没有统计到内存泄漏的原因是相似的,就是没有统计到被检测程序使用的malloc/free的库的地方,也就是说valgrind工具没有找到被检测应用程序相关的系统库的调用。

有了以上思路后,在valgrind运行时,加入了 -v参数,发现关键日志:

​
--9748-- WARNING: Serious error when reading debug info

--9748-- When reading debug info from /ld-2.32.so:

--9748-- failed to stat64/stat this file

​

valgrind找不到/ld-2.32.so,读取不到debug info,通过在mips系统上查找,发现该库是存在的,但是在/lib/目录下,并不在“/”目录下,现在的问题就很清晰了,为什么valgrind会去根目录寻找链接库,如何更改寻找链接库的路径。

4.使用gdb跟踪源码:gdb --args valgrind -v --tool=memcheck --leak-check=full 目标程序

经过调试,最后发现,/ld-2.32.so这个路径的源头,是在代码中从/proc/self/maps文件中读取的,在parse_procselfmaps函数中解析,最终会调用ML_(am_allocate_segname)(const HChar *name),将这个路径名字,填写到segnames[VG_TABLE_SIZE]中,然后解析代码逻辑会从segnames中读取。

总结一下,在mips平台上,/proc/self/maps/文件中显示的ld-2.32.so的路径配置的不对,导致了valgrind在监控时,找不到目标程序调用ld-2.32.so的过程。

解决方案:

正解:找到为什么在/proc/self/maps文件中,ld-2.32.so的路径不对(暂时未定位到)。

野路子:am_allocate_segname函数中,将/ld-2.32.so,改为/lib/ld-2.32.so,这样子也是可以的,想当于魔改了maps文件的解析部分。

说明:

1.maps文件中,大概率不会仅仅是一个ld-2.32.so错误,其他库一样的处理逻辑。

2.在另外一个窗口查看valgrind进程的maps文件时,不要使用self这个pid,要使用“cat /proc/valgrind进程pid/maps”命令。

你可能感兴趣的:(linux,运维,服务器)