Go 是一個靜態語言,想要了解我們寫出來的程式碼到底深入做了哪些事情,從組合語言來看是個很直接的方法。官方有教我們使用 GDB 來解析,但是因為 GDB 並不了解 Go 本身的一些內建 lib 結構,和 Go 運作的模型,所以使用 Delve 這個特製給 Go 的工作是最適合的。
建議直接閱讀官方文件及安裝文件,這邊只帶過一些我覺得好用的指令。
// hello.go
package main
import "fmt"
func main() {
fmt.Printf("hello, 世界\n")
}
$ dlv debug hello.go
Type 'help' for list of commands.
(dlv) r
Process restarted with PID 62368
(dlv) disass main.main
Command failed: wrong number of arguments: disassemble [-a <start> <end>] [-l <locspec>]
(dlv) disass -l main.main
TEXT main.main(SB) ~/go/hello/hello.go
hello.go:5 0x10b6a50 65488b0c2530000000 mov rcx, qword ptr gs:[0x30]
hello.go:5 0x10b6a59 483b6110 cmp rsp, qword ptr [rcx+0x10]
hello.go:5 0x10b6a5d 7642 jbe 0x10b6aa1
hello.go:5 0x10b6a5f 4883ec48 sub rsp, 0x48
hello.go:5 0x10b6a63 48896c2440 mov qword ptr [rsp+0x40], rbp
hello.go:5 0x10b6a68 488d6c2440 lea rbp, ptr [rsp+0x40]
hello.go:6 0x10b6a6d 488d05bd5f0300 lea rax, ptr [rip+0x35fbd]
hello.go:6 0x10b6a74 48890424 mov qword ptr [rsp], rax
hello.go:6 0x10b6a78 48c74424080e000000 mov qword ptr [rsp+0x8], 0xe
hello.go:6 0x10b6a81 48c744241000000000 mov qword ptr [rsp+0x10], 0x0
hello.go:6 0x10b6a8a 0f57c0 xorps xmm0, xmm0
hello.go:6 0x10b6a8d 0f11442418 movups xmmword ptr [rsp+0x18], xmm0
hello.go:6 0x10b6a92 e88989ffff call $fmt.Printf
hello.go:7 0x10b6a97 488b6c2440 mov rbp, qword ptr [rsp+0x40]
hello.go:7 0x10b6a9c 4883c448 add rsp, 0x48
hello.go:7 0x10b6aa0 c3 ret
hello.go:5 0x10b6aa1 e8eaf3f9ff call $runtime.morestack_noctxt
hello.go:5 0x10b6aa6 eba8 jmp $main.main
(dlv) q
$ cat ./hello.go