内存溢出问题

这次务器内存溢出导致崩溃的问题是解决了,可后来仔细想想,其实是有些运气成份的,因为是偶然有个dump可以看到有个模块溢出的内存,继而具体分析相关模块的多个dump才得出结论的。这几天,有个问题一直困扰着这我:以后要是再遇到这类问题,是不是又得投入大量时间精力寻找崩溃点,为此今天再重新查阅当时接收到的服务器崩溃的dump。

存溢出的造成问题的确很诡异,因为内存溢出会破坏程序的内存,从而产生很多崩溃点。这次服务器很多模块都出现崩溃点,大都是服务器在执行malloc、new和free操作时,由于堆被破坏,崩溃了,即heap_corruption。

内存溢出问题_第1张图片

首先是epolsrv_1372214194.dmp,下图是其堆栈,dump显示执行malloc产生崩溃,具体分析其堆栈上相应变量,发现有些变量和实际值不符合,说明是溢出造成,但查看变量内存相应值,没能看出覆盖的内存的特殊性

内存溢出问题_第2张图片

再看看epolsrv_1372202674.dmp,分析其堆栈、堆栈上变量和相应内存,也是一样,没能看出覆盖的内存的特殊性。

内存溢出问题_第3张图片

查看epolsrv_1372115619.dmp,初看其内存比较正常,但还是在执行free时崩溃了

内存溢出问题_第4张图片

最后看看epolsrv_1371573187.dmp,分析其堆栈、堆栈上变量和相应内存,也是一样,没能看出覆盖的内存的特殊性。

内存溢出问题_第5张图片

 到这里,似乎明白了,如果说造成malloc崩溃的原因是内存泄露或者内存溢出导致,那造成free崩溃的原因会是什么呢,就个人知识范围,内存泄露不会导致free崩溃,那就是内存溢出导致的。具体呢?就会是free的内存地址被改写了或者free的内存越界了,虽然内存越界在debug版本下一定会崩溃,但是在release版本不一定不崩溃吧,假如越界的数据破坏了程序后台一些重要的信息时候。

再看看epolsrv_1372115619.dmp,查看其free的内存,并没有发现被覆盖,那会不会是其内存越界导致的,为此,我查看了其内存,如下图所示

内存溢出问题_第6张图片

dwTotalBytes为整个接收到的报文值的长度0x0c90,而实际报文的接收长度是0x0c04,而该内存又是根据报文头部指定长度申请的,如果接收长度大于报文指定长度,程序执行memcpy就会造成越界,从而导致内存崩溃。

因此,以后有类似malloc、new和free相关崩溃的dump时候,free类的dump会是很好的切入点



你可能感兴趣的:(windows)