我正在調試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 關注
- 180 瀏覽
添加回答
舉報
0/150
提交
取消