I was debugging an irrelevant issue in the Linux kernel and saw the etcd process, which was managed by supervisor, was repeatedly hitting page fault exception and receiving SIGSEGV.
I got curious and used objdump to disassemble the program, and found the faulting amd64 instruction to be:
89 04 25 00 00 00 00 mov %eax,0x0
I then looked at the disassembly of a hello world program. I saw a very common pattern in code generated by go compiler, that is at the end of a function, right after ret
, there's a mov
followed by a jmp
back into the function. For example,
0000000000400c00 <main.main>:
400c00: 64 48 8b 0c 25 f0 ff mov %fs:0xfffffffffffffff0,%rcx
400c07: ff ff
...
400c4b: 48 83 7c 24 48 00 cmpq $0x0,0x48(%rsp)
400c51: 74 59 je 400cac <main.main+0xac>
400c53: 48 c7 04 24 c0 fc 47 movq $0x47fcc0,(%rsp)
400c5a: 00
...
400cab: c3 retq
400cac: 89 04 25 00 00 00 00 mov %eax,0x0
400cb3: eb 9e jmp 400c53 <main.main+0x53>
Is this some trick played by go? If so, how does it work? I'm guessing at 0x400c51
it jumps to 0x400cac
, triggers a SIGSEGV
, which is handled and then the next instruction jumps back to 0x400c53
.