信号处理程序中的arm_pc

问题描述

尝试在信号处理程序中打印错误的指令地址,如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中使用。