google coredump 测试

来源:互联网 发布:linux拷贝文件夹到u盘 编辑:程序博客网 时间:2024/06/10 05:18

1. 下载最新的coredump代码

当前最新版本为 1.2.1 。

项目链接: http://code.google.com/p/google-coredumper/

链接给了一个简单的使用方法,我们用这个方法来测试效果

#include <google/coredumper.h>  ...  WriteCoreDump('core.myprogram');  /* Keep going, we generated a core file,   * but we didn't crash.   */

2.安装

sudo ./configure 

sudo make 

sudo make install 

3.测试

集成google的coredumper有两种,一种是把coredumper的源代码加入到自己的程序中,静态编译,另一种是把coredumper当成动态链接库使用,(推荐后一种),这里我们用后一种方法测试效果,代码如下:

#include <stdio.h> //printf#include <stdlib.h>//exit#include <signal.h>//signal#include <google/coredumper.h>//WriteCoreDumpvoid sig_func(int signo){        printf("segment fault: caught signal: %d\n",signo);        if( WriteCoreDump("coredump.txt") ==0 ) {                 printf("success: WriteCoreDump to coredump.txt\n");        } else {                printf("failure: WriteCoreDump to coredump.txt\n");        }           exit(-1);//important, comment the line will lead to dead loop signal}void error1(){    int a = 5/0;}void error2(){    char *q;     q = 0;    q[1] = 's';}int main(){        signal(SIGSEGV, &sig_func);        signal(SIGFPE,  &sig_func);        error1();        //error2();        return 0;}
代码中有两个错误函数,测试的是error1函数,error1会产生SIGFPE除0错误(floating point exception).

exit(-1)很重要,如果没有这行,程序会一直死循环的报错。exit(-1)也可以用函数raise(SIGKILL)来代替

编译链接代码:g++ test1.c -o test1 -g -lcoredumper

-g选项能让gdb的时候显示详细的代码错误(哪个文件,哪一行错误)

-lcoredumper选项指定使用coredumper动态链接库

如何不能执行而是提示:

./test1: error while loading shared libraries: libcoredumper.so.1: cannot open shared object file: No such file or directory

这时需要设置如下:

export LD_LIBRARY_PATH="the/path/to/your/libcoredumper.so.1/file"

执行test1得出结果

此时生成了coredump.txt文件,可以用来看backtrace信息。

执行gdb test1 coredump.txt 进入gdb,执行bt如下:



可以很具体的看出代码的堆栈,上例中调用了exit(-1),如果不调用,程序则会死循环,那么如果我们想在写了堆栈后跳转到出问题的地方继续执行下去呢?goto的话只能在函数内调转,除非所有的函数都写在main函数,实际项目中也不现实,下面是改过后的代码:

#include <stdio.h> //printf#include <stdlib.h>//exit#include <setjmp.h>// jmp_buf, longjmp, setjmp#include <signal.h>//siganl#include <google/coredumper.h>//WriteCoreDumpjmp_buf env;void sig_func(int signo){        printf("segment falut: caught signal: %d\n",signo);        if( WriteCoreDump("coredump.txt") ==0 ) {                 printf("success: WriteCoreDump to coredump.txt\n");        } else {                printf("failure: WriteCoreDump to coredump.txt\n");        }           longjmp(env,1);}void error1(){    int a = 5/0;}void error2(){    char *q;     q = 0;    q[1] = 's';}int main(){        signal(SIGSEGV, &sig_func);        signal(SIGFPE,  &sig_func);        if(setjmp(env) == 0)            error1();        else            fprintf(stderr,"error\n");        //error2();        return 0;}

和之前的代码相比,此代码多了jmp_buf的变量,C函数库提供了setjmp()和longjmp()函数,它们分别承担非局部标号和goto作用。头文件<setjmp.h>申明了这些函数及同时所需的jmp_buf数据类型。    
   原理非常简单: 
   setjmp(env)设置“jump”点,用正确的程序上下文填充jmp_buf对象env。这个上下文包括程序存放位置、栈和框架指针,其它重要的寄存器和内存数据。当初始化完jump的上下文,setjmp()返回0值,所以会调error1函数。 
   出错后在sig_func里调用longjmp(env,value)的效果就是一个非局部的goto或“长跳转”到由env描述的上下文处(也就是到那原来设置env的setjmp()处)。当作为长跳转的目标而被调用时,setjmp()返回value或1(如果r设为0的话)。(记住,setjmp()不能在这种情况时返回0。) 
   通过有两类返回值,setjmp()让你知道它正在被怎么使用。当设置env时,setjmp()如你期望地执行error1;但当作为长跳转的目标时,setjmp()就从外面“唤醒”它的上下文执行fprintf。你可以用longjmp()来终止异常,用setjmp()标记相应的异常处理程序。 

编译链接代码:g++ test1.c -o test1 -g -lcoredumper

执行test1得出结果



原创粉丝点击