backtrace&&backtrace_symbols 查找段错误 打印堆栈信息
2015-07-20 15:08
696 查看
backtrace系列函数:使用范围适合于没有安装GDB或者想要快速理清楚函数调用顺序的情况
backtrace系列函数
1.Function: int backtrace (void
**buffer, int size)//用来获取堆栈信息。size需要获取的堆栈层次,
该函数返回返回值是实际获得的堆栈层次
2.char ** backtrace_symbols (void
*const *buffer, int size) //size 是backtrace的返回值该函数是用来翻译从bacetrace获得的堆栈信息。返回值为存放各个函数的地址 的二维指针。
3.Function: void backtrace_symbols_fd (void
*const *buffer, int size, int fd) 该函数的功能和backtrace_symbols一样只是它的返回字符串是写入文件描术符为fd的文件
出现段错误的时候进程收到的信号
signal(SIGSEGV,set_on_segment_fault);
void set_on_segment_fault(int sig)
{
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_flags = SA_SIGINFO;
act.sa_sigaction = signal_handler;
sigaction(SIGSEGV, &act, NULL);
}
static void signal_handler(int signum, siginfo_t *info, void *arg){
ucontext_t* context= (ucontext_t *)arg;
void* buffer[128] = {0, };
size_t nptr;
int i;
char **strings = NULL;
char cmdLine[128];
char cmdPath[128];
FILE *processFd = NULL;
fprintf(stderr, "==============================================================");
fprintf(stderr, "==============================================================\n");
fprintf(stderr, "(1) SIGSEGV [%d]\n", info->si_signo);
fprintf(stderr,"context : 0x%lX\n",context->uc_mcontext.regs->nip);
fprintf(stderr,"sp : 0x%lX\n",context->uc_mcontext.regs->gpr[1]);
fprintf(stderr, "==============================================================");
fprintf(stderr, "==============================================================\n");
nptr = backtrace(buffer, 128);
fprintf(stderr, "(2) BACKTRACE Count [%d]\n" , nptr);
strings = backtrace_symbols(buffer, nptr);
if(strings == NULL)
{
fprintf(stderr, "backtrace symbols err\n");
fprintf(stderr, "==============================================================");
fprintf(stderr, "==============================================================\n");
fprintf(stderr, "Process PID is %d got signal %d\n", getpid(), signum);
fprintf(stderr, "==============================================================");
fprintf(stderr, "==============================================================\n");
signal(SIGSEGV, SIG_DFL);
raise(SIGSEGV);
}
for (i=0 ; i<nptr; i++)
{
fprintf(stderr, "[%02d]: %s\n", i, strings[i]);
}
if(strings)
{
free(strings);
strings = NULL;
}
mSNPRINTF(cmdPath, "/proc/%d/cmdline", getpid());
processFd = fopen(cmdPath, "r");
if(processFd != NULL)
{
memset(cmdLine, 0, sizeof(cmdLine));
fgets(cmdLine, 128, processFd);
fclose(processFd);
if(strstr(cmdLine, "main_dbg"))
{
struct rlimit core_limit_size;
getrlimit(RLIMIT_CORE, &core_limit_size);
fprintf(stderr, "Current Core Size : [%d]\n", (int)core_limit_size.rlim_cur);
fprintf(stderr, "Max Core Size : [%d]\n", (int)core_limit_size.rlim_max);
core_limit_size.rlim_cur = RLIM_INFINITY;
core_limit_size.rlim_max = RLIM_INFINITY;
setrlimit( RLIMIT_CORE, &core_limit_size );
fprintf(stderr, "Core Size : unlimited [%d][%d]\n", (int)core_limit_size.rlim_cur, (int)core_limit_size.rlim_max);
}
else
{
fprintf(stderr, "==============================================================");
fprintf(stderr, "==============================================================\n");
fprintf(stderr, "Process Name is [%s]\n", cmdLine);
fprintf(stderr, "==============================================================");
fprintf(stderr, "==============================================================\n");
}
}
else
{
fprintf(stderr, "File open failed [%s]\n", cmdPath);
}
fprintf(stderr, "==============================================================");
fprintf(stderr, "==============================================================\n");
fprintf(stderr, "Process PID is %d got signal %d\n", getpid(), signum);
fprintf(stderr, "==============================================================");
fprintf(stderr, "==============================================================\n");
signal(SIGSEGV, SIG_DFL);
raise(SIGSEGV);
}
backtrace系列函数
1.Function: int backtrace (void
**buffer, int size)//用来获取堆栈信息。size需要获取的堆栈层次,
该函数返回返回值是实际获得的堆栈层次
2.char ** backtrace_symbols (void
*const *buffer, int size) //size 是backtrace的返回值该函数是用来翻译从bacetrace获得的堆栈信息。返回值为存放各个函数的地址 的二维指针。
3.Function: void backtrace_symbols_fd (void
*const *buffer, int size, int fd) 该函数的功能和backtrace_symbols一样只是它的返回字符串是写入文件描术符为fd的文件
出现段错误的时候进程收到的信号
signal(SIGSEGV,set_on_segment_fault);
void set_on_segment_fault(int sig)
{
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_flags = SA_SIGINFO;
act.sa_sigaction = signal_handler;
sigaction(SIGSEGV, &act, NULL);
}
static void signal_handler(int signum, siginfo_t *info, void *arg){
ucontext_t* context= (ucontext_t *)arg;
void* buffer[128] = {0, };
size_t nptr;
int i;
char **strings = NULL;
char cmdLine[128];
char cmdPath[128];
FILE *processFd = NULL;
fprintf(stderr, "==============================================================");
fprintf(stderr, "==============================================================\n");
fprintf(stderr, "(1) SIGSEGV [%d]\n", info->si_signo);
fprintf(stderr,"context : 0x%lX\n",context->uc_mcontext.regs->nip);
fprintf(stderr,"sp : 0x%lX\n",context->uc_mcontext.regs->gpr[1]);
fprintf(stderr, "==============================================================");
fprintf(stderr, "==============================================================\n");
nptr = backtrace(buffer, 128);
fprintf(stderr, "(2) BACKTRACE Count [%d]\n" , nptr);
strings = backtrace_symbols(buffer, nptr);
if(strings == NULL)
{
fprintf(stderr, "backtrace symbols err\n");
fprintf(stderr, "==============================================================");
fprintf(stderr, "==============================================================\n");
fprintf(stderr, "Process PID is %d got signal %d\n", getpid(), signum);
fprintf(stderr, "==============================================================");
fprintf(stderr, "==============================================================\n");
signal(SIGSEGV, SIG_DFL);
raise(SIGSEGV);
}
for (i=0 ; i<nptr; i++)
{
fprintf(stderr, "[%02d]: %s\n", i, strings[i]);
}
if(strings)
{
free(strings);
strings = NULL;
}
mSNPRINTF(cmdPath, "/proc/%d/cmdline", getpid());
processFd = fopen(cmdPath, "r");
if(processFd != NULL)
{
memset(cmdLine, 0, sizeof(cmdLine));
fgets(cmdLine, 128, processFd);
fclose(processFd);
if(strstr(cmdLine, "main_dbg"))
{
struct rlimit core_limit_size;
getrlimit(RLIMIT_CORE, &core_limit_size);
fprintf(stderr, "Current Core Size : [%d]\n", (int)core_limit_size.rlim_cur);
fprintf(stderr, "Max Core Size : [%d]\n", (int)core_limit_size.rlim_max);
core_limit_size.rlim_cur = RLIM_INFINITY;
core_limit_size.rlim_max = RLIM_INFINITY;
setrlimit( RLIMIT_CORE, &core_limit_size );
fprintf(stderr, "Core Size : unlimited [%d][%d]\n", (int)core_limit_size.rlim_cur, (int)core_limit_size.rlim_max);
}
else
{
fprintf(stderr, "==============================================================");
fprintf(stderr, "==============================================================\n");
fprintf(stderr, "Process Name is [%s]\n", cmdLine);
fprintf(stderr, "==============================================================");
fprintf(stderr, "==============================================================\n");
}
}
else
{
fprintf(stderr, "File open failed [%s]\n", cmdPath);
}
fprintf(stderr, "==============================================================");
fprintf(stderr, "==============================================================\n");
fprintf(stderr, "Process PID is %d got signal %d\n", getpid(), signum);
fprintf(stderr, "==============================================================");
fprintf(stderr, "==============================================================\n");
signal(SIGSEGV, SIG_DFL);
raise(SIGSEGV);
}
相关文章推荐
- Linux socket 初步
- 10 篇对初学者和专家都有用的 Linux 命令教程
- Linux 与 Windows 对UNICODE 的处理方式
- Ubuntu12.04下QQ完美走起啊!走起啊!有木有啊!
- 解決Linux下Android开发真机调试设备不被识别问题
- 运维入门
- 运维提升
- Linux 自检和 SystemTap
- Ubuntu Linux使用体验
- c语言实现hashmap(转载)
- Linux 信号signal处理机制
- linux下mysql添加用户
- Scientific Linux 5.5 图形安装教程
- 基于 Linux 集群环境上 GPFS 的问题诊断
- 谁是桌面王者?Win PK Linux三大镇山之宝
- vivi下重新调整分区
- Linux VS Unix:Linux欲一统天下 Unix不死
- linux下设定环境变量