This is a creation in Article, where the information may have evolved or changed.
Note: This writer is YANN, the original is Introduction to Go debugging with GDB
Over the last 4 years, I've spent most of my time writing, reading, and debugging Python or JavaScript code. In the process of learning Go, like wearing a pair of small stone shoes in the beautiful mountains. A lot of things left a deep impression on me, but using println
debugging My code went too far in the past. In Python, when the code is running, we use pdb/ipdb
debugging it, and JavaScript provides a similar tool. Over the years, this pattern has become a very important part of my workflow.
Today, I realized that go has built-in support for Gnu debugger (aka GDB).
For this article, we use the following simple procedure:
package mainimport ( "fmt" "time")func counting(c chan<- int) { for i := 0; i < 10; i++ { time.Sleep(2 * time.Second) c <- i } close(c)}func main() { msg := "Starting main" fmt.Println(msg) bus := make(chan int) msg = "starting a gofunc" go counting(bus) for count := range bus { fmt.Println("count:", count) }}
In order to use GDB, you need to -gcflags ”-N -l”
compile your program with options that prevent the compiler from using inline functions and variables.
go build -gcflags "-N -l" gdbsandbox.go
This is an interactive debugging of the GDB session example:
yml@simba$ gdb gdbsandbox GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2) 7.4-2012.04Copyright (C) 2012 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later
First, we run our program:
(gdb) runStarting program: /home/yml/Developments/go/src/gdbsandbox/gdbsandbox Starting maincount: 0count: 1count: 2[...]count: 9[Inferior 1 (process 13507) exited normally]
Now that we know how to run our program, we may want to set a breakpoint.
(gdb) help break Set breakpoint at specified line or function.break [LOCATION] [thread THREADNUM] [if CONDITION]LOCATION may be a line number, function name, or "*" and an address.[...](gdb) break 22Breakpoint 1 at 0x400d7a: file /home/yml/Developments/go/src/gdbsandbox/gdbsandbox.go, line 22.(gdb) runStarting program: /home/yml/Developments/go/src/gdbsandbox/gdbsandbox Starting main[New LWP 13672][Switching to LWP 13672]Breakpoint 1, main.main () at /home/yml/Developments/go/src/gdbsandbox/gdbsandbox.go:2222
Once GDB stops at your breakpoint, you will see the context:
(gdb) help listList specified function or line.With no argument, lists ten more lines after or around previous listing."list -" lists the ten lines before a previous ten-line listing.[...](gdb) list17 msg := "Starting main"18 fmt.Println(msg)19 bus := make(chan int)20 msg = "starting a gofunc"21 go counting(bus)22 for count := range bus {23 fmt.Println("count:", count)24 }25 }
You can also check the variables:
(gdb) help printPrint value of expression EXP.Variables accessible are those of the lexical environment of the selectedstack frame, plus all those whose scope is global or an entire file.[...](gdb) print msg$1 = "starting a gofunc"
In the early days of the code, we started one goroutine
, and when I went to line 10th, I wanted to check out this part of my program.
(gdb) break 10Breakpoint 3 at 0x400c28: file /home/yml/Developments/go/src/gdbsandbox/gdbsandbox.go, line 10.(gdb) help continueContinue program being debugged, after signal or breakpoint.If proceeding from breakpoint, a number N may be used as an argument,which means to set the ignore count of that breakpoint to N - 1 (so thatthe breakpoint won't break until the Nth time it is reached).[...](gdb) continueContinuing.
The last thing we need to do today is to change the value of a variable at run time:
Breakpoint 3, main.counting (c=0xf840001a50) at /home/yml/Developments/go/src/gdbsandbox/gdbsandbox.go:1010 time.Sleep(2 * time.Second)(gdb) help whatisPrint data type of expression EXP.Only one level of typedefs is unrolled. See also "ptype".(gdb) whatis counttype = int(gdb) print count$3 = 1(gdb) set variable count=3(gdb) print count$4 = 3(gdb) cContinuing.count: 3
We have only covered the following commands:
- List
- Next
- Print
- Continue
- Break
- Whatis
- Set Variable=
This is almost all about using GDB's surface knowledge, and if you want to learn more about GDB, here are more links:
- http://sourceware.org/gdb/current/onlinedocs/gdb/
- Http://golang.org/doc/gdb