eis/TestProject/json_test/src/segvCatch.h

98 lines
2.9 KiB
C
Raw Normal View History

/*
* : leehomwu
* : 2011-05-14
* : 2011-06-11, EIP
* :
* 使: main
* : STDOUT打印调用路径上的指令地址
signal[8] catched when running code at 80486f0
signal[8] catched when running code at 80488ea
signal[8] catched when running code at 80488d9
:
addr2line 80486f0 80488ea 80488d9 -s -C -f -e
[]
main
newsig.cpp:14
a()
kk.cpp:23
b()
kk.cpp:19
*/
#ifndef __SEGV_CATCH_H
#define __SEGV_CATCH_H
#include <execinfo.h>
#include <signal.h>
#include <stdio.h>
#ifndef __USE_GNU
#define __USE_GNU
#include <sys/ucontext.h>
#include <ucontext.h>
#undef __USE_GNU
#else
#include <sys/ucontext.h>
#include <ucontext.h>
#endif
#ifdef __cplusplus
static void initSegvCatch(void);
class C_SEGVCATCH {
public:
C_SEGVCATCH() { initSegvCatch(); }
};
static C_SEGVCATCH C_segv_catch;
#else
static void initSegvCatch(void) __attribute__((constructor));
#endif
static void OnSIGSEGV(int, siginfo_t*, void*);
static void initSegvCatch() {
struct sigaction act;
sigemptyset(&act.sa_mask);
act.sa_sigaction = OnSIGSEGV;
act.sa_flags = SA_SIGINFO;
if (sigaction(SIGSEGV, &act, NULL) < 0 || sigaction(SIGFPE, &act, NULL) < 0) {
perror("sigaction:");
}
}
static void OnSIGSEGV(int signum, siginfo_t* info, void* ptr) {
static int iTime;
if (iTime++ >=
1) { /* 容错处理:如果访问 ucontext_t 结构体时产生错误会进入该分支 */
printf("ReEnter %s is not allowed!\n", __FUNCTION__);
abort();
}
void* array[25];
int nSize = backtrace(array, sizeof(array) / sizeof(array[0]));
int i;
for (i = nSize - 3; i > 2; i--) { /* 头尾几个地址不必输出 */
/* 对array修正一下使地址指向正在执行的代码 */
printf("signal[%d] catched when running code at %x\n", signum,
(long)array[i] - 1);
}
if (NULL != ptr) {
ucontext_t* ptrUC = (ucontext_t*)ptr;
int* pgregs = (int*)(&(ptrUC->uc_mcontext.gregs));
int eip = pgregs[REG_RIP];
if (eip != (long)array[i]) { /* 有的处理器会将出错时的 EIP 入栈 */
printf("signal[%d] catched when running code at %x\n", signum,
(long)array[i] - 1);
}
printf("signal[%d] catched when running code at %x\n", signum,
eip); /* 出错时的指令地址 */
} else {
printf("signal[%d] catched when running code at unknown address\n", signum);
}
abort();
}
#endif // __SEGV_CATCH_H