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)
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.
User contributions licensed under CC BY-SA 3.0