解决C可执行程序出现munmap_chunk()的错误

本周在做事的时候,我把代码提交上去后,对程序进行了下测试,出现了munmap_chunk(),程序直接崩溃。dump了core文件。gdb对core文件进行调试查看。崩溃处是因为程序调用了free接口。但是仔细看了代码,并不觉得有什么错误。查了下,stackoverflow上也是说对野指针进行了操作。也就是内存操作上有些错误吧。因此用内存调试工具valgrind,运行了一下可执行程序,结果打印出来的log也是果真是指针free操作失误了。

因为我们这边工程有自己的内存管理机制,而这次提交我代码中申请内存用的是工程自带的内存管理,但是释放内存也就是free的时候却是用系统的free()接口。导致libc库报错。由于是公司代码,这里只好写一小段代码进行模拟下。

gcc编译后,并执行下

说白了,就是一个异常的地址,free的时候会对内存分页进行校验的时候,出现了错误。所以最好的解决办法就是用valgrind对内存进行检测,并查看警告的log打印。对应去找代码。即可解决问题。

其实这还没结束。本来我以为会很容易重现的。结果我试了好多次。经常报错的却是free(): invalid pointer。把上文中的words = words+1改为words+3或其余的值,当然如果你+0其实还是本来地址,这其实是合法的。执行结果如下:

偏移量不一样,竟然得到的log也不一样,并且如果申请的地址大小不一样,报错的结果也不一样。我们还是将最早的代码,将512改为256的大小。运行结果将和第二个的报错一样。因此特地去下了下libc6的代码。

通过gdb调试core文件,可以看到报错在这里:

在malloc.c的4965行,内容如下:

c库真是凶残,各种宏,单这个malloc.c就有5000+行。大概看了下malloc_printerr用来打印错误信息的,malloc.c中是会对内存进行校验的,而内存分配其实有个内存页大小的,不同的内存分配大小校验也不大一样,导致打印的错误也不一样,没打算深究下去。对于分页大小的话,这个在ubuntu上可以通过命令查看:

可能第一个做+1,并且申请内存为512刚好使得标识为munmap_chunk的操作,而+3或内存申请不为512时,走到另一个标识上了,也没细看这部分的代码。太多了,也太懒得看了。总之,出现这种问题,其实还算是好办的,内存检测开起来,跑一下,并且对照代码看看指针是否有哪些误操作。当然,如果工程太大,确实会比较麻烦,所以C的指针还是要用好,并且要管理好,我们这边出现这种状况,就是指针乱飞,一个地方申请,另一个地方去做释放。谁也不知道哪天哪里出现问题了,找都会找死了,尤其是那些偶现的问题。

这里再补充下valgrind进行内存检测的log吧:

 

BTW:看来C库对内存的维护还是很复杂的,所以有时候内存不应该频繁申请释放,这在很多开源的项目中,都有体现,有一些很不错的内存池管理开源库之类的。都是很值得去学习的。以上的测试基于ubuntu 15.04版本进行测试,C库为glibc(2.21),不同平台的话,可能多少有些差异,但是都差不多的处理方式。

参考链接:

How to solve munmap_chunk(): invalid pointer error in C++

 

 

转载请注明: 转载自elkPi.com

本文链接地址: 解决C可执行程序出现munmap_chunk()的错误

2 Responses to “解决C可执行程序出现munmap_chunk()的错误

  • amberkaka
    3周 ago

    我也遇到了同样的报错信息,在别的地方查的解决方案没用,在你这里看后把free那句删掉就行了,感谢!

    • 呃,但是如果你确实是malloc出来的,没有free可是会内存泄漏的!

发表评论

电子邮件地址不会被公开。 必填项已用*标注