`

关于linux的段错误(Segmentation fault)

 
阅读更多

1.Segmentation fault这个字符串在shell中是谁打印的?
这个字符串实际上是bash(或者别的shell)打印的,而不是当前出错的进程,也不是内核,参见bash源代码的WAITPID (-1, &status, 0))语句。因此如果在一个自己写的程序中不对子进程进程任何wait或者不捕捉子进程退出信号的话,即使是段错误也不会打印信息,正如下面的程序一样,程序将默默终止:
int main(int argc, char **argv)
{
        if (fork() == 0){
            int *ad = (int *)0;
            *ad = 1234;
        }
}
linux中内核或者标准库连这么严重的段错误都不处理,足以看出其机制和策略分离的特性,用户可以自己处理,然后如果父进程感兴趣的话就通知父进程处理,反正内核和底层库是不管的,如果进程本身不处理,那么进行默认处理,而这个默认处理就是退出出错进程,然后父进程如果想做点什么,它可以wait退出进程,然后从status中得到信息。
2.段错误信号是可以被捕获的,一旦捕获了,那么行为就可能是任意的,只有编写捕获钩子的家伙知道。
3.段错误的调试方法:产生core文件,然后gdb proname corename,输入where/bt
4.段错误有时很有用:如果你不明白backtrace和backtrace_symbols函数,在一个很大的代码中你怎么知道某一个函数在特定参数的情况下被什么地方调用,比如有一个函数:
void test(char *name, char *value, ...)
{
    ...
}
你不知道当name是"abc"的时候,什么地方调用了test,完全可以这样:
void test(char *name, char *value, ...)
{
    if (!strcmp(name, "abc")) {
        int *a = (int *)0;
        *a = 1234;
    }
    ...
}
然后用gdb调试core文件即可。
5.有的时候段错误很奇怪,很有可能是编译问题,比如是头文件的版本不对或者连接库不对导致的二进制不兼容引起的,将头文件整理好,库匹配正确之后,重新干净的编译。

 

转:http://blog.csdn.net/dog250/article/details/5735520

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics