Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1950984
  • 博文数量: 77
  • 博客积分: 2175
  • 博客等级: 大尉
  • 技术积分: 2491
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-20 20:49
个人简介

欢迎光临我的博客

文章分类

全部博文(77)

文章存档

2023年(1)

2018年(4)

2017年(1)

2016年(2)

2015年(2)

2013年(5)

2012年(29)

2010年(33)

分类: LINUX

2010-05-24 22:02:49

     coredump是我们在调试程序时经常碰到的问题,分析coredump的方法多种多样:分析日志;
编译一个含符号表的debug版binary,在产生coredump后,使用一些调试工具gdb,dbx等分析core文件。这里介绍一种不借助于日志和gdb等工具,完全手工分析的办法。
    以常见的非法地址访问引起的
coredump为例,它会触发11号信号----SIGSEGV.
   

#define STACK_BACK_SIZE    0x100
void SegFaultHandler(int signo)
{
    int trace;
    int *p = &trace;
    int i;
    for(i = 0; i < STACK_BACK_SIZE; i++)
        syslog(LOG_DEBUG, "stack: %p:%x", p,*p++);

    exit(signo);
}
    
void main()
{
    signal(SIGSEGV, SegFaultHandler);
     ... ...
}


在产生coredump时,触发信号SIGSEGV,由于其处理函数已被注册为SegvHandler,则SegvHandler被调用。
SegvHandler所做的就是打印出当前栈上STACK_BACK_SIZE个整数。根据这STACK_BACK_SIZE个整数,再反汇编binary代码,就可以确定coredump所产生的指令。
这是因为如果某条指令产生coredump,那么SegvHandler的返回地址就是该指令的下一条指令,当然实际在coredump发生时,系统可能会增加对libc.so中mutex_lock等的调用,再调用SegvHandle,栈空间是:
--------->SegFaultHandler (栈顶)
---------------->mutex_lock(libc.so)
-------------------------->引起coredump指令的下一条指令
如果最终编译生成的binary文件是a.out,使用readelf或objdump将a.out反汇编,就可以知道栈空间上的对应内容,也就是SegFaultHandler中打印出的各值的含义,不外乎是返回地址,保存的寄存器值和局部变量等。

如果是在linux平台下,那么就不需要分析符号表,而可以调用backtrace来打出当前调用栈从而知道哪个函数导致coredump,但注意link时要加上 -rdynamic选项,否则符号表内容不清楚:
  1. #include <execinfo.h>

  2. void print_trace()
  3. {
  4.         void *array[40];
  5.         size_t size;
  6.         char **strings;
  7.         size_t i;

  8.         size = backtrace (array, 40);
  9.         strings = backtrace_symbols (array, size);

  10.         for (i = 0; i < size; i++)
  11.         {
  12.        printf("##callstack##%s\n", strings[i]);

  13.         }
  14.         printf("\n");
  15.         free (strings);

  16. }

void SegFaultHandler(int signo)
{
    int trace;
    print_trace();

    exit(signo);
}
    
void main()
{
    signal(SIGSEGV, SegFaultHandler);
     ... ...
}

如果是在其他平台上,也可以获得当前栈信息,具体请参照下面的文章:
在AIX下如何在程序中获得当前调用栈信息

《返璞归真--UNIX技术内幕》在全国各大书店及网城均有销售:
                         
                       


阅读(17148) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~