/proc/sys/vm/max_map_count耗尽时,调用glibc 2.11.3 free()导致程序crash,问题追踪和解决
来源:互联网 发布:印尼越南 知乎 编辑:程序博客网 时间:2024/05/03 07:49
1. 问题
在客户环境下,当我们的程序消耗较大内存时,会偶尔crash。
通过gdb分析,程序core dump在malloc/free函数内。
当把/proc/sys/vm/max_map_count 从65530增加到131070,程序再也不crash。
相关命令 echo 131073 > /proc/sys/vm/max_map_count
2. core dump 分析
Thread 1 (Thread 20074): #0 0x00007fbb77afd6d5 in raise () from/lib64/libc.so.6
#1 0x00007fbb77afecb1in abort () from /lib64/libc.so.6
#2 0x00007fbb77b43a0d in __malloc_assert () from /lib64/libc.so.6 #3 0x00007fbb787ea6a8 in
#3 不再给出,涉及保密
...
...
运行环境是SUSE 11 SP3, 其glibc 版本是2.11.3。
通过读glibc 2.11.3 代码,发现一个可疑点:
https://github.com/lzueclipse/learning/blob/master/c_cpp/glibc-2.11.3/malloc/malloc.c#L3552
当free()时,如果/proc/sys/vm/max_map_count 被耗尽,那么munmap系统调用会失败,就会导致assert,并core dump。
下面我们来试图证明这个分析是正确的。
3. 通过Google搜索找到一个类似的问题
Google搜索“munmap_chunk assert”,找到:
https://sourceware.org/bugzilla/show_bug.cgi?id=13276
报的问题是:
When a process runs out of virtual mappings on Linux (more mmaps than /proc/sys/vm/max_map_count) then munmap can fail because it may need to split a mapping.
在这个bug下面,给出了一个重现这个bug的test case:
https://sourceware.org/bugzilla/attachment.cgi?id=5967
我在第4节中会利用这个测试用例重现bug。
针对这个bug的fix:
https://www.sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=6ef76f3b515c45a83f7831f806bf97a2af9ed008
可以看出,当munmap失败时,glibc不在assert,这个fix在glibc 2.15以及后续版本中。
4. 测试并重现bug
4.1 代码和测试环境
对
https://sourceware.org/bugzilla/attachment.cgi?id=5967
进行了少量修改,以便我加入一些pmap调试信息,我的代码在:
https://github.com/lzueclipse/learning/blob/master/c_cpp/malloc_free_bug_2.11.3/mmap_malloc_test.c
测试将在SUSE 11 SP3(glibc 2.11.3)和SUSE 12(glibc 2.19)上进行,期望的行为是:
程序在SUSE 11 SP3 crash,但是在SUSE 12上运行正常。
4.2 在SUSE 11 SP3上的测试
1)ulimit -c unlimited
不限制core file大小。
2) gcc -g mmap_malloc_test.c
编译,有符号。
3) ./a.out
cnt=65530, ps=4096
.........
19
.........
19
.........
19
.........
65531
a.out: malloc.c:3546: munmap_chunk: Assertion `ret == 0'failed.
Aborted (core dumped)
可以看出:
“/proc/sys/vm/max_map_count” 的值是65530,当超过它时(65531),crash在了free()。
pmap调试信息在:
https://github.com/lzueclipse/learning/blob/master/c_cpp/malloc_free_bug_2.11.3/pmap1.txt
https://github.com/lzueclipse/learning/blob/master/c_cpp/malloc_free_bug_2.11.3/pmap2.txt
https://github.com/lzueclipse/learning/blob/master/c_cpp/malloc_free_bug_2.11.3/pmap3.txt
https://raw.githubusercontent.com/lzueclipse/learning/master/c_cpp/malloc_free_bug_2.11.3/pmap4.txt
4) gdb -c ./core a.out
GNU gdb (GDB) SUSE (7.5.1-0.7.29)
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-suse-linux".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/robinwan/public_html/a.out...done.
[New LWP 9003]
Missing separate debuginfo for /lib64/libc.so.6
Try: zypper install -C
"debuginfo(build-id)=89f460a6502702332c336f3cd7f5568036483b98"
Missing separate debuginfo for /lib64/ld-linux-x86-64.so.2
Try: zypper install -C
"debuginfo(build-id)=38ab807fcca391af7d3ed7fcf585fbff2d54556a"
Core was generated by `./a.out'.
Program terminated with signal 6, Aborted.
#0 0x00007fd5f369db55 in raise () from /lib64/libc.so.6
(gdb) bt
#0 0x00007fd5f369db55 in raise () from /lib64/libc.so.6
#1 0x00007fd5f369f131 in abort () from /lib64/libc.so.6
#2 0x00007fd5f36e183d in __malloc_assert () from /lib64/libc.so.6
#3 0x000000000040097d in main () at mmap_malloc_test.c:42 《======42行,就是free().
4.3 在SUSE 12上的测试
./a.out
cnt=65530, ps=4096
.........
19
.........
19
.........
19
.........
65531
.........
end!!!
“/proc/sys/vm/max_map_count” 的值是65530,当超过它时(65531),没有crash。
5.结论
一旦遇到类似问题,如果glibc版本是2.11.x ---2.14.x,只能增加“/proc/sys/vm/max_map_count”;
从glibc 2.15.x,这个问题已经被修复。
- /proc/sys/vm/max_map_count耗尽时,调用glibc 2.11.3 free()导致程序crash,问题追踪和解决
- /proc/sys/vm/max_map_count耗尽时,调用glibc 2.11.3 free()导致程序crash,问题追踪和解决
- 生产上数据库大量的latch free 导致的CPU资源耗尽的问题的解决
- /proc/sys/vm/优化
- /proc/sys/vm/
- /proc/sys/vm
- /proc/sys/vm
- /proc/sys/vm/drop_caches
- /proc/sys/vm/优化
- proc /sys/vm 终结版
- /proc/sys/vm虚拟内存参数。
- cat /proc/sys/vm/swappiness
- 清理系统缓存 echo 3 > /proc/sys/vm/drop_caches
- glibc malloc和free
- VirtualProtect导致程序crash的问题。
- 有关/proc/sys/vm/drop_caches的用法
- /proc/sys/vm参数(转)
- Linux内核参数,proc/sys/vm/…
- 初学android开发,百度sdk——地图篇(1.1)
- 扑克牌
- CSS笔记2
- iOS类似Android的ViewPager
- android学习笔记(一)__安装环境
- /proc/sys/vm/max_map_count耗尽时,调用glibc 2.11.3 free()导致程序crash,问题追踪和解决
- Android 异步消息处理机制(Handler 、 Looper 、MessageQueue)源码解析
- 监听日志太大,有10g怎么破?
- ubuntu安装chrome
- beego模板语法 go语言模版语法
- UVAlive--4529--Dangerous Tunnels(二分+拆点最大流)
- GCD主队列、全局队列
- 柴俊理金:美指强势回归打压,金价受挫原油逆袭
- Android仿斗鱼领取鱼丸文字验证(三)