Chinaunix首页 | 论坛 | 博客
  • 博客访问: 179884
  • 博文数量: 108
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 1065
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-29 08:56
文章分类

全部博文(108)

文章存档

2011年(11)

2010年(46)

2009年(29)

2008年(22)

我的朋友

分类: LINUX

2010-05-26 09:32:19

arm-uclibc-gcc 栈回溯:

uclibc  不支持 :(

添加编译选项
CFLAGS+= -mapcs-frame
还要生成map文件比对地址
-Wl,-Map,device.map

通过
__builtin_return_address(0);  
__builtin_frame_address(0);
导出当前帧。
里面包含上一级栈帧逐级回溯。


参考:

#define RECORD_FILE_SIZE 2048
extern unsigned long __etext;          
extern unsigned long __executable_start;

void back_trace(void)
{
   
     // volatile int *i;
      volatile unsigned int *pfun;
      int m=1;
      int * ret = __builtin_return_address(0); 
      int * cstack0 = __builtin_frame_address(0);
      unsigned int ptextb = (int)(&__executable_start);
      unsigned int ptexte = (int)(&__etext);
     
                
        printf("EXE: 0x%x-0x%x\r\n", ptextb, ptexte);      
           
      #ifndef  RESET_LOG_PRINT
         FILE * reset_record_fd;
         struct stat statf;
        
         printf("\r\nRESET\r\n");            
         reset_record_fd = fopen("/var/config/reset_record.txt","a+");         
         fstat(fileno(reset_record_fd),&statf);        
        // printf("filesize: %ld \r\n",statf.st_size);
       if( statf.st_size >= RECORD_FILE_SIZE )
       {
             fclose(reset_record_fd);
               reset_record_fd = fopen("/var/config/reset_record.txt","w+");
       }   
       //               
      #else
         syslog("RESET!\r\n");
      #endif
     
   
        #ifndef  RESET_LOG_PRINT       
      printf("return0 addr:%p\r\n", ret);
      fprintf(reset_record_fd,"\r\nreturn0 addr:%p\r\n", ret);
    #else
      syslog("return0 addr:%p\r\n", ret );
    #endif
    
     pfun =  *(cstack0-3);   
   
     do{
            #ifndef  RESET_LOG_PRINT
           printf("return%d addr:0x%x\r\n", m, *(pfun-1));
           fprintf(reset_record_fd,"return%d addr:0x%x\r\n", m, *(pfun-1));
         #else
              syslog("return%d addr:0x%x\r\n", m, *(pfun-1) );
           #endif
          
           pfun = *(pfun - 3);
           m++;
      }
     while( ( ptextb < (*(pfun-1)) )&&( (*(pfun-1)) <  ptexte ) );
    
     
      #ifndef  RESET_LOG_PRINT
         printf("return%d addr:0x%x\r\n", m, *(pfun-1) );
         fprintf(reset_record_fd,"return%d addr:0x%x\r\n", m, *(pfun-1));
      #else
         syslog("return%d addr:0x%x\r\n", m, *(pfun-1) );
      #endif
     
       #ifndef  RESET_LOG_PRINT
         printf("stack0 addr:%p\r\n", cstack0);
         fprintf(reset_record_fd,"stack0 addr:%p\r\n", cstack0);
         fflush(reset_record_fd);
         fclose(reset_record_fd);
         //save
      #else
         syslog("stack0 addr:%p\r\n", cstack0 );
      #endif
     
      
   
     /*
     #define STACK_DEEP 24
     for(i =cstack0-STACK_DEEP;i < cstack0+1; i++)
     {
        #ifndef  RESET_LOG_PRINT
             printf("stack [%p]:0x%x \r\n", i,*i);
           #else
             syslog("stack [%p]:0x%x \r\n", i,*i );
           #endif
     } 
     #undef STACK_DEEP
     */

      sleep(3);
    
      return;
}
阅读(1592) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~