我正在调试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.
1 回答
千万里不及你
TA贡献1784条经验 获得超9个赞
我从 Go 开发人员那里得到了一些答案:https : //groups.google.com/forum/#!topic/ golang-nuts/ _7yio3ZfVBE
基本上,这种模式是过时实现中的 nil 检查。引用的是 Keith Randall 的回答。
如果指针为零,则跳转到产生错误的指令。该错误用于启动 nil ptr panic。
这是一个非常低效的代码序列。jmps 似乎从未被使用过。升级到更新的 Go 版本,您会看到它已得到改进。
- 1 回答
- 0 关注
- 239 浏览
添加回答
举报
0/150
提交
取消
