我正在调试Linux内核中一个无关紧要的问题,看到由supervisor管理的etcd进程反复遇到页面错误异常并收到SIGSEGV。
我很好奇并使用 objdump 反汇编程序,发现错误的 amd64 指令是:
89 04 25 00 00 00 00 mov %eax,0x0
然后我查看了一个 hello world 程序的反汇编。我在 go 编译器生成的代码中看到了一个很常见的模式,就是在一个函数的末尾,紧跟在 之后ret,mov然后是一个jmpback 到函数中。例如,
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>
这是 go 玩的什么把戏吗?如果是这样,它是如何工作的?我猜0x400c51它会跳转到0x400cac,触发 a SIGSEGV,它被处理,然后下一条指令跳回0x400c53.
千万里不及你
相关分类