以下是我的代码,在我交叉编译libunwind之后,想实现崩溃等异常抓取,然后生成日志。
但是调试的时候发现,unwind在崩溃的时候无法获取到堆栈,崩溃发生的时候,无法获得有效的堆栈,读PC IP寄存器都是0。unw_step直接返回0了。
我编译选项已经包含了符号表以及unwind-table。
此外我GDB调试的时候,bt是可以正常追溯到堆栈的。
希望大佬指点一二。
当前环境:
Linux
编译选项:
CC_FLAG=-Wall -O0 -fno-strict-aliasing -DBINDER_IPC_32BIT=1 -g -rdynamic -funwind-tables -fno-omit-frame-pointer
static void libunwind_backtrace(void)
{
int32_t ret, count, len, max_len;
unw_cursor_t cursor;
unw_context_t context;
unw_word_t offset, pc, sp;
char fname[256], comm_name[32];
char buffer[8096];
printf("============libunwind_backtrace===================\n");
/* Initialize cursor to current frame for local unwinding. */
if (unw_getcontext(&context) != 0) {
printf("unw_getcontext error.\n");
return;
}
if (unw_init_local(&cursor, &context) != 0) {
printf("unw_init_local error.\n");
return;
}
/* 获取当前线程名字, 通过prctl */
memset(comm_name, 0, sizeof(comm_name));
if (prctl(PR_GET_NAME, comm_name) != 0) {
printf("prctl error : %s(%d).\n", strerror(errno), errno);
snprintf(comm_name, sizeof(comm_name), "(unknown)");
}
len = 0;
max_len = sizeof(buffer);
count = 0;
len += snprintf(buffer, (size_t)max_len, "Stack trace for [%s]:\n", comm_name);
// Unwind frames one by one, going up the frame stack.
while ((ret = unw_step(&cursor)) > 0){
printf("===unw_step ret[%d]\n", ret);
if (unw_get_reg(&cursor, UNW_REG_IP, &pc) != 0) {
printf("unw_get_reg error.\n");
continue;
}
/* 获取栈指针SP的值 */
if (unw_get_reg(&cursor, UNW_REG_SP, &sp) != 0) {
printf("unw_get_reg error.\n");
continue;
};
ret = unw_get_proc_name(&cursor, fname, sizeof(fname), &offset);
printf("ret %d offset %d\n", ret, offset);
if (ret != 0) {
snprintf(fname, sizeof(fname), "??????");
offset = 0;
}
len += snprintf(buffer + len, (size_t)(max_len - len),
"[%2d]-> PC 0x%-12lx, SP 0x%-12lx: [%s](+0x%lx)\n", count++, pc, sp, fname, offset);
if (len >= max_len - 1) {
break;
}
}
printf("===end unw_step ret[%d]\n", ret);
buffer[sizeof(buffer) - 1] = '\0'; /* Ensure null termination. */
printf("%s", buffer);
return;
}