C代码的coredump

1. 概述

C程序崩溃之后会自动转存储,利用这个信息可以快速定位出错的地方。


但要正确地使用这个功能,需要注意如下几点:

  • 代码在编译的时候,添加调试选项-g
  • 设置转存储的大小(有些系统缺省为0)
  • 结合gdb和coredump文件定位异常点


2. 示例1


示例代码:

#include <stdio.h>

int core_dump() {
	int i;

	for (i = 5; i >= 0; i--) {
		printf("(%d, %d)\n", i, 100 / i);
	}

	return 0;
}

int main() {
	core_dump();

	return 0;
}

以上代码存在除0异常,编译运行:

gcc main.c
./a.out

运行结果:

(5, 20)
(4, 25)
(3, 33)
(2, 50)
(1, 100)
[1]    9662 floating point exception (core dumped)  ./a.out


为了更清楚地找到代码出错的地方,可以使用gdb来分析coredump文件:

~/examples/cpp/core_dump % gdb ./a.out core
GNU gdb (GDB) 7.7
Copyright (C) 2014 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 "i686-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./a.out...done.
[New LWP 9662]

warning: Could not load shared library symbols for linux-gate.so.1.
Do you need "set solib-search-path" or "set sysroot"?
Core was generated by `./a.out'.
Program terminated with signal SIGFPE, Arithmetic exception.
#0  0x08048415 in core_dump ()
(gdb) where
#0  0x08048415 in core_dump ()
#1  0x0804844b in main ()
(gdb) q

可以看到上面并没有给出具体的代码&行号,因为需要添加-g编译选项。为此重新编译、运行,此时的coredumnp文件就提供了全面的信息:

~/examples/cpp/core_dump % gdb ./a.out core
GNU gdb (GDB) 7.7
Copyright (C) 2014 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 "i686-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./a.out...done.
[New LWP 9758]

warning: Could not load shared library symbols for linux-gate.so.1.
Do you need "set solib-search-path" or "set sysroot"?
Core was generated by `./a.out'.
Program terminated with signal SIGFPE, Arithmetic exception.
#0  0x08048415 in core_dump () at main.c:7
7                       printf("(%d, %d)\n", i, 100 / i);
(gdb) where
#0  0x08048415 in core_dump () at main.c:7
#1  0x0804844b in main () at main.c:14
(gdb) 

3. 示例2:ulimit设置转存储大小

下面这个例子是在一台新安装Ubuntu 12后第一次运用内存转存储的功能,期间遇到转存储后无法找到core文件。此时,就需要用ulimit命令设置转存储的大小。


代码如下:

#include <stdio.h> //fopen etc
#include <string.h> //strlen
int main() 
{
	const char* s = "hello";
	FILE* fp = NULL;
	fp = fopen("./hello_c.txt", "rb");
	fwrite(s, 1, strlen(s), fp);
	fclose(fp);
	return 0;
}

编译、运行:

flying-bird@flying-bird:~/examples/cpp/echo$ gcc -g ./hello.c 
flying-bird@flying-bird:~/examples/cpp/echo$ ./a.out 
段错误 (核心已转储)
flying-bird@flying-bird:~/examples/cpp/echo$ ll
总用量 24
drwxrwxr-x 2 flying-bird flying-bird 4096  5月 10 15:19 ./
drwxrwxr-x 3 flying-bird flying-bird 4096  5月 10 15:19 ../
-rwxrwxr-x 1 flying-bird flying-bird 9464  5月 10 15:19 a.out*
-rw-rw-r-- 1 flying-bird flying-bird  211  5月 10 15:17 hello.c
flying-bird@flying-bird:~/examples/cpp/echo$ 

虽然提示已经转存储了,但仍然找不到core文件。为此查询core大小,并修改:

flying-bird@flying-bird:~/examples/cpp/echo$ ulimit -c
0
flying-bird@flying-bird:~/examples/cpp/echo$ ulimit -c unlimited
flying-bird@flying-bird:~/examples/cpp/echo$ ./a.out 
段错误 (核心已转储)
flying-bird@flying-bird:~/examples/cpp/echo$ ll
总用量 352
drwxrwxr-x 2 flying-bird flying-bird   4096  5月 10 15:21 ./
drwxrwxr-x 3 flying-bird flying-bird   4096  5月 10 15:19 ../
-rwxrwxr-x 1 flying-bird flying-bird   9464  5月 10 15:19 a.out*
-rw------- 1 flying-bird flying-bird 335872  5月 10 15:21 core
-rw-rw-r-- 1 flying-bird flying-bird    211  5月 10 15:17 hello.c
flying-bird@flying-bird:~/examples/cpp/echo$ 

此时,生成了core文件,然后就可以用于定位问题了:

flying-bird@flying-bird:~/examples/cpp/echo$ gdb ./a.out core
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
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 "i686-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/flying-bird/examples/cpp/echo/a.out...done.
[New LWP 4108]

warning: Can't read pathname for load map: 输入/输出错误.
Core was generated by `./a.out'.
Program terminated with signal 11, Segmentation fault.
#0  0xb761e775 in fwrite () from /lib/i386-linux-gnu/libc.so.6
(gdb) where
#0  0xb761e775 in fwrite () from /lib/i386-linux-gnu/libc.so.6
#1  0x080484ca in main () at ./hello.c:8
(gdb) q
flying-bird@flying-bird:~/examples/cpp/echo$ 

4. 补充

  • 并不是所有的异常都会生成coredump文件,具体请参考《Unix环境高级编程(2nd)》第十章 信号。
  • 有时候需要在代码中动态执行ulimit的功能,为此需要调用getrlimit()和setrlimit()函数。具体请参考《Advanced Linux Programming》8.5节。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值