- 论坛徽章:
- 0
|
回复 19# zhayun604863141
找打一个现成的了,在init中注册该信号函数试试,看能否在挂的是否打印出调用栈。 实现原理参照百度搜索“基于MIPS架构的BackTrace实现”
如果不行的话,将其提前到内核中捕捉异常信息时打印,移到内核时,访问用户内存时,注意下使用get_user。- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <signal.h>
- #include <ucontext.h>
-
- #define abs(s) ((s) < 0 ? -(s) : (s))
-
- #define CALL_TRACE_MAX_SIZE (10)
-
- #define MIPS_ADDIU_SP_SP_XXXX (0x27bd0000) /* instruction code for addiu sp, sp, xxxx */
- #define MIPS_SW_RA_XXXX_SP (0xafbf0000) /* instruction code for sw ra, xxxx(sp) */
- #define MIPS_ADDU_RA_ZERO_ZERO (0x0000f821) /* instruction code for addu ra, zero, zero */
- void getCodeIn(unsigned long codeAddr, char *pCodeIn, int iCodeInSize, unsigned long *pOffset)
- {
- FILE *pFile = NULL;
- char szLine[1000] = {0};
- pFile = fopen("/proc/self/maps", "r");
- if ( pFile != NULL )
- {
- while (fgets(szLine, sizeof(szLine), pFile))
- {
- char *pTmp = NULL;
- char szAddr[500] = {0};
- char szCodeIn[500] = {0};
- unsigned long begin = 0;
- unsigned long end = 0;
- sscanf(szLine, "%s %*s %*s %*s %*s %s", szAddr, szCodeIn);
- pTmp = strchr(szAddr, '-');
- if ( pTmp != NULL )
- {
- *pTmp++ = '\0';
- begin = strtoul(szAddr, NULL, 16);
- end = strtoul(pTmp, NULL, 16);
- }
- if ( codeAddr >= begin && codeAddr <= end )
- {
- strncpy(pCodeIn, szCodeIn, iCodeInSize);
- *pOffset = codeAddr - begin;
- return;
- }
- }
- fclose(pFile);
- }
- strncpy(pCodeIn, "unknown", iCodeInSize);
- *pOffset = 0;
- }
- int backtrace_mips32(void **buffer, int size, ucontext_t *uc)
- {
- unsigned long *tmpl = NULL;
- unsigned long *addr = NULL;
- unsigned long *ra = NULL;
- unsigned long *sp = NULL;
- unsigned long *pc = NULL;
- size_t ra_offset = 0;
- size_t stack_size = 0;
- int depth = 0;
- if (size == 0)
- {
- return 0;
- }
- if (buffer == NULL || size < 0 || uc == NULL)
- {
- return -1;
- }
- pc = (unsigned long *)(unsigned long)uc->uc_mcontext.pc;
- ra = (unsigned long *)(unsigned long)uc->uc_mcontext.gregs[31];
- sp = (unsigned long *)(unsigned long)uc->uc_mcontext.gregs[29];
- buffer[0] = pc;
- if ( size == 1 )
- {
- return 1;
- }
- for ( addr = pc; !ra_offset || !stack_size; --addr )
- {
- if ( ((*addr) & 0xffff0000) == MIPS_SW_RA_XXXX_SP)
- {
- ra_offset = (short)((*addr) & 0xffff);
- }
- else if ( ((*addr) & 0xffff0000) == MIPS_ADDIU_SP_SP_XXXX)
- {
- stack_size = abs((short)((*addr) & 0xffff));
- }
- else if ( (*addr) == MIPS_ADDU_RA_ZERO_ZERO )
- {
- return 1;
- }
- }
- if ( ra_offset > 0 )
- {
- tmpl = (unsigned long *)((char *)sp + ra_offset);
- ra = (unsigned long *)(*tmpl);
- }
- if ( stack_size > 0 )
- {
- sp = (unsigned long *)((unsigned long)sp + stack_size);
- }
- for (depth = 1; depth < size && ra; ++depth)
- {
- buffer[depth] = ra;
- ra_offset = 0;
- stack_size = 0;
- for (addr = ra; !ra_offset || !stack_size; --addr)
- {
- if ( ((*addr) & 0xffff0000) == MIPS_SW_RA_XXXX_SP)
- {
- ra_offset = (short)((*addr) & 0xffff);
- }
- else if ( ((*addr) & 0xffff0000) == MIPS_ADDIU_SP_SP_XXXX)
- {
- stack_size = abs((short)((*addr) & 0xffff));
- }
- else if ( (*addr) == MIPS_ADDU_RA_ZERO_ZERO )
- {
- return depth + 1;
- }
- }
- tmpl = (unsigned long *)((char *)sp + ra_offset);
- ra = (unsigned long *)(*tmpl);
- sp = (unsigned long *)((unsigned long)sp + stack_size);
- }
- return depth;
- }
- void signal_process(int sig_no, siginfo_t *sig_info, void *ucontext)
- {
- int i = 0;
- unsigned long *callStack[CALL_TRACE_MAX_SIZE] = {0};
- printf("\r\n*******************************************\r\n");
- printf("recv signo %d\r\n", sig_no);
- backtrace_mips32((void **)callStack, CALL_TRACE_MAX_SIZE, (ucontext_t *)ucontext);
- printf("\r\ncall tracing:\r\n");
- for ( i = 0; i < CALL_TRACE_MAX_SIZE; i++ )
- {
- char szCodeIn[100] = {0};
- unsigned long addrOffset = 0;
- if ( callStack[i] == 0 )
- {
- break;
- }
- getCodeIn((unsigned long)callStack[i], szCodeIn, sizeof(szCodeIn), &addrOffset);
- printf("\t[%02d] addr 0x%08x(offset 0x%08x), in %s\r\n", i, callStack[i], addrOffset, szCodeIn);
- }
- printf("*******************************************\r\n");
- if (sig_no == SIGSEGV)
- {
- signal(sig_no, SIG_DFL);
- }
- sleep(3);
- }
- void c(void)
- {
- int *p = 0;
- printf("I am function [c]\r\n");
- *p = 888;
- }
- void b(void)
- {
- printf("I am function [b]\r\n");
- c();
- }
- void a(void)
- {
- printf("I am function [a]\r\n");
- b();
- }
- int main(int argc, char *argv[])
- {
- struct sigaction act = {0};
- act.sa_sigaction = signal_process;
- sigemptyset(&act.sa_mask);
- act.sa_flags = SA_SIGINFO;
- sigaction(SIGSEGV, &act, NULL);
- printf("I am function [main]\r\n");
- a();
- return 0;
- }
复制代码 |
|