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

问题现象
今天在研究linux kernel中typedef的用法时,写了一个程序test_typedef.c,内容如下:

#include

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可执行程序的分析结果如下:
段错误(核心已转储)问题的分析方法_第1张图片
由上图可以看出,通过core file定位出来的问题代码行也是37行,说明分析结果的准确性。
core file的产生:
core file文件是在程序异常退出时产生的,程序的异常退出往往是通过信号(signal)产生的,但并不是所有的信号都能够产生core file,在signal.h的头文件中定义了哪些signal可以产生core file,如下:
段错误(核心已转储)问题的分析方法_第2张图片
段错误(核心已转储)问题的分析方法_第3张图片
上图中所有default action为coredump的中断信号都可以产生core file。
除了中断信号必须能够产生coredump外,还必须进行如下设置:
1)、ulimit –c unlimited (设置core file的大小,相当于使能core file的生成)
2)、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

你可能感兴趣的:(kernel,linux驱动)