siginfo_t will not work, because it contains the address of the memory to which it was accessed , and not the address of the instruction that it is.
Now __builtin_return_address interesting. On my machine, it returns some nonsense:
0x40089f ~ 0x400935 ~ 0x40093f si:0 At: 0x7fe22916fc20 At: 0x7fe22915ad8e
I have no idea why. But then I examined the core dump:
(gdb) bt #0 0x00000000004009ff in handler(int, siginfo*, void*) () #1 <signal handler called> #2 0x0000000000400939 in main ()
As you can see, as in your case, the violation address is somewhere between the labels. This is easy to explain. Just look at the disassembly of main ():
(gdb) disas Dump of assembler code for function main: ... ; the label is here: 0x0000000000400935 <+161>: mov -0x8(%rbp),%rax => 0x0000000000400939 <+165>: movl $0x0,(%rax) 0x000000000040093f <+171>: mov $0x400c32,%esi
The designated operator consists of several instructions. The first loads the address into the RAX register. It succeeds because there is nothing wrong with that. This is the second one that accesses the address and is broken. This explains why the address in your trace is slightly different from the label address, although the code is likely to be different from my example. This all does not explain why __builtin_return_address gives stupidity in my case.
Sergey Tachenov
source share