段错误(核心已转储)问题的分析方法

问题现象
今天在研究linux kernel中typedef的用法时,写了一个程序test_typedef.c,内容如下:
#include<stdio.h>
typedef int size;
typedef unsigned int word;
typedef char line[81];
typedef void (*printStr)(line text);
typedef printStr * pprintStr;
typedef char * pstr;
void printText(line text){
printf("%s\n", text);
}
void * pppPrintText(line text){
printf("%s\n", text);
}
pprintStr pprintText(){
//return &printText;
printStr temp = printText;
return (printStr *)temp;
}
/*void (*pprintText)(line text){
printf("%s\n", text);
}*/
void main(){
size i=10;
word w = 20;
line text;
printf("%d, %d, %d\n",i, w, sizeof(text)/sizeof(char));
printStr printFun = printText;
pprintStr pprintFun = pprintText();
printFun("test typedef");
//((printStr)pprintFun)("test pointer typedef");
(*pprintFun)("test pointer typedef");
char string[4] = "abc";
pstr p1 = string;
const char *p2 = string;
p1++;
p2++;
printf("%s, %s\n", p1, p2);
}
加上37行的代码(*pprintFun)(“test pointer typedef”);后,通过gcc –o typedef test_typdef.c命令编译成typedef可执行文件后执行,出现段错误:
之前也遇见过“段错误(核心已转储)”(Segmentation fault(core dumped)),但是没有进行分析,今天借着这个机会学习一下这类问题的分析方法。
段错误的分析方法
段错误一般借助于可调试(使用-g选项进行编译)的原程序和核心转储后的core file来进行分析,如针对我写的程序,其步骤为:
- gcc –g –o typedef test_typedef.c (生成可调试的可执行程序)
- ./typedef (产生段错误,生成core file)
- gdb –c core_file typdef (使用core file调试产生段错误的可执行程序)
- 在gdb调试环境中执行bt或where命令定位到问题行
按如上步骤对typedef可执行程序的分析结果如下:
由上图可以看出,通过core file定位出来的问题代码行也是37行,说明分析结果的准确性。
core file的产生
core file文件是在程序异常退出时产生的,程序的异常退出往往是通过信号(signal)产生的,但并不是所有的信号都能够产生core file,在signal.h的头文件中定义了哪些signal可以产生core file,如下:
上图中所有default action为coredump的中断信号都可以产生core file。
除了中断信号必须能够产生coredump外,还必须进行如下设置:
- ulimit –c unlimited (设置core file的大小,相当于使能core file的生成)
- ulimit unlimited (设置file的大小)
其他问题
1. core file存放在哪个目录
存放core file一般存放在进程的当前工作目录,一般就是当初发出命令启动该进程时所在的目录。但如果是通过脚本启动,则脚本可能会修改当前目录,这时进程真正的当前目录就会与当初执行脚本所在目录不同。这时可以查看"/proc/pid/cwd"符号链接的目标来确定进程真正的当前目录地址。
2. core file的文件名
一般core file的文件名即为core,可能通过
echo "1" > /proc/sys/kernel/core_uses_pid
将core file的文件名改为core.pid
3. 如何修改core file的文件名格式和保存位置
/proc/sys/kernel /core_pattern可以控制core文件保存位置和文件名格式。可通过以下命令修改此文件:
echo "/corefile/core-%e-%p-%t" >/proc/sys/kernel /core_pattern
可以将core文件统一生成到/corefile目录下,产生的文件名为core-命令名-pid-时间戳
以下是参数列表:
%p - insert pid into filename 添加pid
%u - insert current uid into filename 添加当前uid
%g - insert current gid into filename 添加当前gid
%s - insert signal that caused the coredump into the filename 添加导致产生core的信号
%t - insert UNIX time that the coredump occurred into filename 添加core文件生成时的unix时间
%h - insert hostname where the coredump happened into filename 添加主机名
%e - insert coredumping executable name into filename 添加命令名
4. 如果你当初是以用户A运行了某个程序,但在ps里看到的这个程序的用户却是B的话,那么这些进程就是调用了seteuid了。为了能够让这些进程生成core dump,需要将/proc/sys/fs/suid_dumpable 文件的内容改为1(一般默认是0)
参考技术文章
- http://www.cnblogs.com/yunlong3727/archive/2013/05/21/3090797.html




更多推荐
所有评论(0)