coreファイルを使ったgoのデバッグ
以下の記事を参考にcore dumpからgoプログラムのデバッグする方法をためしてみた。
Analyzing Core Dump Generated By Go Program - Speaker Deck
C言語の場合gdbを使うが、go言語の場合、dlvを使うようだ。
覚えておいて損はなさそう。ただし、macosではcoreファイルが作成されないようだ。残念。
$ ulimit -c unlimited $ cat main.go package main func main() { var p *int p = nil *p = 1 } $ export GOTRACEBACK=crash $ go build main.go $ ./main panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x44ebb2] goroutine 1 [running]: panic(0x45d560, 0x4b7ce0) /usr/local/go/src/runtime/panic.go:556 +0x2cb fp=0xc000032720 sp=0xc000032690 pc=0x421edb runtime.panicmem() /usr/local/go/src/runtime/panic.go:82 +0x5e fp=0xc000032740 sp=0xc000032720 pc=0x420f1e runtime.sigpanic() /usr/local/go/src/runtime/signal_unix.go:390 +0x182 fp=0xc000032790 sp=0xc000032740 pc=0x4342f2 main.main() /home/unokun/work/go/main.go:6 +0x2 fp=0xc000032798 sp=0xc000032790 pc=0x44ebb2 runtime.main() /usr/local/go/src/runtime/proc.go:201 +0x207 fp=0xc0000327e0 sp=0xc000032798 pc=0x423bc7 runtime.goexit() /usr/local/go/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc0000327e8 sp=0xc0000327e0 pc=0x448d21 goroutine 2 [force gc (idle)]: runtime.gopark(0x470bd8, 0x4b9ae0, 0x1410, 0x1) /usr/local/go/src/runtime/proc.go:302 +0xeb fp=0xc000032f80 sp=0xc000032f60 pc=0x423fab runtime.goparkunlock(0x4b9ae0, 0x1410, 0x1) /usr/local/go/src/runtime/proc.go:308 +0x53 fp=0xc000032fb0 sp=0xc000032f80 pc=0x424053 runtime.forcegchelper() /usr/local/go/src/runtime/proc.go:251 +0xb3 fp=0xc000032fe0 sp=0xc000032fb0 pc=0x423e23 runtime.goexit() /usr/local/go/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc000032fe8 sp=0xc000032fe0 pc=0x448d21 created by runtime.init.4 /usr/local/go/src/runtime/proc.go:240 +0x35 goroutine 3 [GC sweep wait]: runtime.gopark(0x470bd8, 0x4b9ba0, 0x41140c, 0x1) /usr/local/go/src/runtime/proc.go:302 +0xeb fp=0xc000033780 sp=0xc000033760 pc=0x423fab runtime.goparkunlock(0x4b9ba0, 0x47140c, 0x1) /usr/local/go/src/runtime/proc.go:308 +0x53 fp=0xc0000337b0 sp=0xc000033780 pc=0x424053 runtime.bgsweep(0xc000052000) /usr/local/go/src/runtime/mgcsweep.go:52 +0x8f fp=0xc0000337d8 sp=0xc0000337b0 pc=0x418a9f runtime.goexit() /usr/local/go/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc0000337e0 sp=0xc0000337d8 pc=0x448d21 created by runtime.gcenable /usr/local/go/src/runtime/mgc.go:216 +0x58 [1] 29625 abort (core dumped) ./main $ ls core.29625 main main.go $ dlv core main core.29625 Type 'help' for list of commands. (dlv) bt 0 0x000000000044a624 in runtime.raise at /usr/local/go/src/runtime/sys_linux_amd64.s:146 1 0x00000000004344ab in runtime.dieFromSignal at /usr/local/go/src/runtime/signal_unix.go:424 2 0x0000000000434928 in runtime.sigfwdgo at /usr/local/go/src/runtime/signal_unix.go:629 3 0x0000000000433d08 in runtime.sigtrampgo at /usr/local/go/src/runtime/signal_unix.go:289 4 0x000000000044a913 in runtime.sigtramp at /usr/local/go/src/runtime/sys_linux_amd64.s:353 5 0x000000000044aa00 in runtime.sigreturn at /usr/local/go/src/runtime/sys_linux_amd64.s:445 6 0x000000000043466a in runtime.crash at /usr/local/go/src/runtime/signal_unix.go:518 7 0x00000000004224d7 in runtime.fatalpanic at /usr/local/go/src/runtime/panic.go:708 8 0x0000000000421edb in runtime.gopanic at /usr/local/go/src/runtime/panic.go:556 9 0x0000000000420f1e in runtime.panicmem at /usr/local/go/src/runtime/panic.go:82 10 0x00000000004342f2 in runtime.sigpanic at /usr/local/go/src/runtime/signal_unix.go:390 11 0x000000000044ebb2 in main.main at ./main.go:6 12 0x0000000000423bc7 in runtime.main at /usr/local/go/src/runtime/proc.go:201 13 0x0000000000448d21 in runtime.goexit at /usr/local/go/src/runtime/asm_amd64.s:1333 (dlv) frame 11 > runtime.raise() /usr/local/go/src/runtime/sys_linux_amd64.s:146 (PC: 0x44a624) Warning: debugging optimized function Frame 11: ./main.go:6 (PC: 44ebb2) 1: package main 2: 3: func main() { 4: var p *int 5: p = nil => 6: *p = 1 7: } (dlv) locals p = (unreadable empty OP stack) (dlv) disass TEXT main.main(SB) /home/unokun/work/go/main.go main.go:6 0x44ebb0 31c0 xor eax, eax main.go:6 0x44ebb2 48c70001000000 mov qword ptr [rax], 0x1 main.go:7 0x44ebb9 c3 ret (dlv) regs ... Rax = 0x0000000000000000 ... (dlv)