化妆品网站网页设计,如何建立设计一个公司网站,手机活动网站模板,营销型网站制作多少钱Bug描述#xff1a;压力测试一个小工程时发现内存逐渐减少#xff0c;10个小时后出现OOM
Bug定位过程#xff1a;
对整个工程模块进行分解#xff0c;逐步缩小范围#xff0c;由于整个工程包括几个相对独立的小模块#xff0c;而整个工程采用单进程多线程的模型#x…Bug描述压力测试一个小工程时发现内存逐渐减少10个小时后出现OOM
Bug定位过程
对整个工程模块进行分解逐步缩小范围由于整个工程包括几个相对独立的小模块而整个工程采用单进程多线程的模型导致进行分解时要特别注意相互之间的耦合只能逐步分离各个模块运行测试这里如果采用多进程模型定位会更快一些一个完整的功能放在一个进程和多进程中多进程天然的将功能细化了定位问题范围更小在经过一段折磨人的拆分过程后最后把问题定位到整个工程中一个小模块功能内。在对该模块进行了反复的代码review后没有发现什么异常甚至没有内存申请的操作。代码层面没有找到突破的情况下重新通过各种命令查看了内存状态由于在此之前一直通过free命令查看内存发现长时间后free命令输出的可用内存在逐渐减少但忽略了一点通过top命令单独查看模块进程占用的内存时该进程的rss段一直保持稳定没有大幅度增长。基于前一步的发现怀疑是kernel的内存有泄漏查看/proc/meminfo发现一个疑点slab内存占用很高且SUnreclaim的slab一直在增加此时基本确定kernel内存泄漏。通过kmemleak对内核内存进行了分析定位在到一个函数接口中
char *wr_pr_debug_begin(u8 const *data, u32 len, char *string)
{int ii;string kmalloc(len * 2 1, GFP_KERNEL);for (ii 0; ii len; ii)sprintf(string[ii * 2], %02X, data[ii]);string[len * 2] 0;return string;
}
char *wr_pr_debug_end(char *string)
{kfree(string);return ;
}
void test()
{char *read 0;pr_debug(%s RD%02X%02X%02X - %s%s\n, st-hw-name,i2c_addr, reg, length,wr_pr_debug_begin(data, length, read),wr_pr_debug_end(read));
}
一眼可能不容易看出上面的有什么问题有kmalloc有kfree啊好像成对出现的。 考验基本功的时候到了熟悉函数调用传参的人应该会知道编译器一般对参数的处理采用堆栈的方式是一个先进后出的过程这样参数的执行一般是逆序的由于编译器实现的不同这个过程不是确定的这样kfree会在kmalloc之前运行导致每次运行都会泄漏一点内存。上面是一个debug输出暂时注释掉后压测问题解决内存保持稳定。
总结整个定位过程其实比较简单如果第一步看下/proc/meminfo可能会更快的定位问题由于这个kernel driver是“大厂”提供以为不会出问题一直从上层的角度去找问题所以没有太关注kernel相关内存的使用导致内存泄漏的原因也很简单出现这种问题的原因首先编写者的基本功一般更主要的原因是编写者出于“炫技”的方式去写了这段代码如果老老实实封装一个debug函数按照正常顺序调用也就没有问题了而且这种每次打印进行kmalloc的方式对性能也是有些影响的。总之基本功还是很重要而且不要驾驭自己驾驭不了的编码方式。