问题描述
尝试在信号处理程序中打印错误的指令地址,如https://devarea.com/linux-writing-fault-handlers/#comment-12995
所示由于某种原因,每次我打印p-> uc_mcontext.arm_pc内容时,都会得到不同的结果,这对gdb来说没有意义。 如果我使用gdb运行相同的程序并使用“信息寄存器”打印寄存器,则每次运行都会看到一致的PC值,这也使我可以看到错误的代码
信号处理程序中的相关代码:
@H_404_7@static void My_Signals_handler(int sig,siginfo_t *info,void *extra) { ucontext_t *p; printf("Received Signal: %d\n",sig); switch(sig) { case SIGFPE: case SIGSEGV: case SIGILL: case SIGBUS: p = (ucontext_t *)extra; printf("siginfo address=%x\n",info->si_addr); printf("arm_pc address = 0x%X\n",p->uc_mcontext.arm_pc); printf("arm_sp address = 0x%X\n",p->uc_mcontext.arm_sp); printf("arm_lr address = 0x%X\n",p->uc_mcontext.arm_lr); printf("arm_r0 address = 0x%X\n",p->uc_mcontext.arm_r0); /* make sure buffer is printed to stodut before we crash */ fflush(stdout); /* restore to default signal handler so core dump is generated from original fault point */ RegisterForSignals(true); return; break; default: printf("unkNown signal %d\n",sig); /* restore to default signal handler so core dump is generated from original fault point */ RegisterForSignals(true); return; } return; }
输出(每次运行都会更改):
@H_404_7@Received Signal: 11 siginfo address=0 arm_pc address = 0x44D3AE arm_sp address = 0xBEEFFCC0 arm_lr address = 0x44D3AD arm_r0 address = 0x0
与gdb一起运行时
@H_404_7@(gdb) info registers r0 0x0 0 r1 0x0 0 r2 0xffffffff 4294967295 r3 0x4bb268 4960872 r4 0x494680 4802176 r5 0x494ea4 4804260 r6 0x0 0 r7 0x0 0 r8 0x455 1109 r9 0x465 1125 r10 0x4946b4 4802228 r11 0x4bb168 4960616 r12 0x0 0 sp 0xbefffcc0 0xbefffcc0 lr 0x4033ad 4207533 pc 0x4033ae 0x4033ae <main(int,char**)+526> cpsr 0x40070030 1074200624 fpscr 0x0 0 (gdb)
解决方法
好的,问题是ASLR随机分配地址。当我禁用ASLR时,arm_pc地址与gdb输出的地址相同。 由于这不是永久解决方案,因此我使用了backtrace API来打印回溯,并从应用程序的开头获取了偏移量。该地址可以在gdb中使用。