arm_pc in signal handler

0

Trying to print the faulting instruction address in my signal handler as demonstrated in https://devarea.com/linux-writing-fault-handlers/#comment-12995

for some reason each time I print p->uc_mcontext.arm_pc content I get a different result which doesn't make sense to gdb. if I run the same program with gdb and print the registers with "info registers" I see a consistent PC value on each run which also allows me to see the faulty code

relevant code in signal handler:

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

output (changes on every run):

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

when running with 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) 

                                                            
c
arm
gdb
interrupt-handling
asked on Stack Overflow Nov 12, 2020 by Amir

1 Answer

0

ok the issue was ASLR randomizing the addresses. when I've disabled ASLR the arm_pc address was the same as the one output by gdb. since this cannot be a perpetual solution I've used the backtrace API to print the backtrace and with it I got the offset from the beginning of my application. that address can be used in gdb.

answered on Stack Overflow Nov 22, 2020 by Amir

User contributions licensed under CC BY-SA 3.0