内存转储
<引自> http://www.cublog.cn/u/18537/showart_139634.html在程序莫明其妙地当掉之时,操作系统就会把程序当掉时的内存内容 dump 出来(现在通常是写在一个叫 core 的 file 里面),以让我们或 是 debugger 做为参考,这种行为名曰core dump。很多人将其翻译为 “内核转储”,我觉得不通,应该叫“内存转储”,下文我将以“内存转储文 件”这个名词来取代程序崩溃文件。
可能我们用的这个Linux发行版为了节约硬盘空间,默认状态下会将内存 转储功能关闭了,若将其打开,需要在shell配置文件(如 bash的.bash_profile)中添加:
ulimit -c unlimited
默认状态下,程序崩溃时,生成的内存转储文件位于该程序所在目录 下,且名为"core.pid",pid时崩溃程序的进程号。我们可以通过修改位 于 /proc/sys/kernel目录下的core_uses_pid和corecore_pattern文 件,来控制内存转储文件的存放位置和命名方式。
我建议的设置时去掉内存转储文件的pid,因为它只会增加字符输入工 作,别无它用。另外,为了便于管理,建议将内存转储文件(去掉 pid后,名为 core)放在一个指定目录(譬如corefiles)下。这样在使用 gdb进行调试时,只需要“gdb 程序名 corefiles/core"即可。也许你觉 得将内存转储文件名设置与你的程序名一致会更好一些。那么,怎样才 可以实现呢,如下:
* echo "0" > /proc/sys/kernel/core_uses_pid
* echo "/tmp/corefiles/%e" >/proc/sys/kernel/core_pattern
上面,第一句是设置pid无效,如果将"0"设置为"1"就是让它起效。第二 句中,/tmep/corefiles是内存转储文件所在目录,这里要特别注意必须 首先创建这样一个目录,然后才可以在core_pattern中进行设置,不然 总是无法成功的。%e是将崩溃程序名作为内存转储文件名。最后,也许 你会觉得每次在使用内存转储文件都要输入其所在目录,这样很繁琐, 你可以为该目录做一个环境变量,譬如$core,可以降低输入量。shell 配置文件设置完毕,在shell下,"source 配置文件名",即可让其起效。
如果,想再多了解一下内存转储文件的知识,可参考这里(如果该链接无 效,可以google关键字"Controlling core files“)。
内存转储功能比较有用的是使用命令”gdb 被调试程序 内存转储文件”, 进入gdb后键入bt或where命令, 就可以显示出出程序是在哪一行当掉的, 还有在当掉时在哪个函数里, 这个函数是被哪个函数所调用的, 而这个 调用函数又是被哪个函数所调用的.... 一直到 main()。根据这个信息, 可以找出五六成的 bug,不过也有例外的情况,比如本文所举的例子中 有一个就属于例外。
