There seems to be a lack of documentation and tutorials around debugging golang using gdb. Here is a short tutorial to get people started.
Here is our golang example project.
- gdbtest/ - main.go
Inside main.go we have
package main import "fmt" type MyStruct struct { x string i int f float64 m map[string] int64 } func main() { x := "abc" i := 3 fmt.Println(i) fmt.Println(x) ms := &MyStruct{ x: "cba", i: 10, f: 11.10335, m: make(map[string]int64), } ms.m["hello"] = int64(11) ms.m["world"] = int64(22) fmt.Println(ms) }
In order to inspect our golang project at runtime, we need to compile it into a binary. Compile main.go golang source file
go build -gcflags "-N"
Next, open up gdb and point it at our compiled binary
gdb gdbtest # or gdb <PROJECT_NAME>
Using the br command, create a breaking point marker at line numer 26. So when we do run the program, execution will block on the instruction located at line number 26.
(gdb) br 26 Breakpoint 1 at 0x2443: file /go/src/github.com/cevaris/gdbtest/main.go, line 26.
Now execute the program.
(gdb) run Starting program: /go/src/github.com/cevaris/gdbtest/gdbtest 3 abc [New Thread 0x1117 of process 99831] Breakpoint 1, main.main () at /go/src/github.com/cevaris/gdbtest/main.go:26 26 fmt.Println(ms) (gdb)
Now that we have a running process of our app and stopped it’s execution after all our variables loaded; we now have acecss to the variables these variables in gdb. We will use the info locals command.
(gdb) info locals i = 3 ms = 0x2081ba1b0 x = 0xdb470 "abc" (gdb)
Notice the value of the ms variable “0x2081ba1b0″. That is the value of the pointer address, or where the instance of the struct MyStruct is stored. In order to inspect the values of the ms variable, we need to print the dereferenced value of ms.
(gdb) print ms $1 = (struct main.MyStruct *) 0x2081ba1b0 (gdb) print *ms $2 = {x = 0xdbb10 "cba", i = 10, f = 11.103350000000001, m = 0x2081ba180} (gdb) print *ms.f (gdb) print ms.f $3 = 11.103350000000001
So, debugging golang with gdb is great for the previous examples, but currently there is a lack of features. In particular, if we wanted to inspect the value of a given map. There is currently no up-to-date way of inspecting map values.
(gdb) print ms.m $4 = (map[string]int64) 0x2081ba180 (gdb) print *ms.m $5 = {count = 2, flags = 0, hash0 = 626927918, B = 0 '\000', buckets = 0x2081bc5b0, oldbuckets = 0x0, nevacuate = 0}
The code is stored here if you want to try gdb debugging yourself.
https://github.com/cevaris/gdbtest
Here is full gist
Сейчас активно развивается отладчик Delve, со временем он может стать неплохой альтернативой gdb для Go
English: Delve is an actively developed debugger; over time it can become a good alternative to gdb for Go