我正在調(diào)試Linux內(nèi)核中一個(gè)無關(guān)緊要的問題,看到由supervisor管理的etcd進(jìn)程反復(fù)遇到頁(yè)面錯(cuò)誤異常并收到SIGSEGV。我很好奇并使用 objdump 反匯編程序,發(fā)現(xiàn)錯(cuò)誤的 amd64 指令是:89 04 25 00 00 00 00 mov %eax,0x0然后我查看了一個(gè) hello world 程序的反匯編。我在 go 編譯器生成的代碼中看到了一個(gè)很常見的模式,就是在一個(gè)函數(shù)的末尾,緊跟在 之后ret,mov然后是一個(gè)jmpback 到函數(shù)中。例如,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它會(huì)跳轉(zhuǎn)到0x400cac,觸發(fā) a SIGSEGV,它被處理,然后下一條指令跳回0x400c53.
1 回答

千萬里不及你
TA貢獻(xiàn)1784條經(jīng)驗(yàn) 獲得超9個(gè)贊
我從 Go 開發(fā)人員那里得到了一些答案:https : //groups.google.com/forum/#!topic/ golang-nuts/ _7yio3ZfVBE
基本上,這種模式是過時(shí)實(shí)現(xiàn)中的 nil 檢查。引用的是 Keith Randall 的回答。
如果指針為零,則跳轉(zhuǎn)到產(chǎn)生錯(cuò)誤的指令。該錯(cuò)誤用于啟動(dòng) nil ptr panic。
這是一個(gè)非常低效的代碼序列。jmps 似乎從未被使用過。升級(jí)到更新的 Go 版本,您會(huì)看到它已得到改進(jìn)。
- 1 回答
- 0 關(guān)注
- 176 瀏覽
添加回答
舉報(bào)
0/150
提交
取消