arm_pc 在信号处理程序中

arm_pc in signal handler

尝试在我的信号处理程序中打印错误指令地址,如 https://devarea.com/linux-writing-fault-handlers/#comment-12995

中所示

出于某种原因,每次我打印 p->uc_mcontext.arm_pc 内容时,我都会得到不同的结果,这对 gdb 没有意义。 如果我 运行 使用 gdb 的相同程序并使用“信息寄存器”打印寄存器,我会在每个 运行 上看到一致的 PC 值,这也让我看到了错误代码

信号处理程序中的相关代码:

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;
}

输出(每个 运行 的变化):

Received Signal: 11
siginfo address=0
arm_pc address = 0x44D3AE
arm_sp address = 0xBEEFFCC0
arm_lr address = 0x44D3AD
arm_r0  address = 0x0

当 运行 gdb

(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 输出的地址相同。 因为这不是一个永久的解决方案,所以我使用了回溯 API 来打印回溯,并使用它从我的应用程序开始处获得了偏移量。该地址可以在 gdb 中使用。