This is a creation in Article, where the information may have evolved or changed.
11.2 Debugging the development program with GDB debugging code is a common thing developers often do, the go language is not like PHP, Python and other dynamic languages, as long as the changes do not need to compile the direct output, and can be dynamic in the running environment to print data. Of course, the go language can also be debugged by printing data such as println, but every time it is necessary to recompile, this is a very troublesome thing. We know that there are tools such as pdb/ipdb in Python, and JavaScript has similar tools, which are capable of dynamically displaying variable information, single-step debugging, and so on. Fortunately, go also has similar tools to support: GDB. The go inside has built-in support for GDB, so we can debug through GDB, so this section describes how to debug the Go program with GDB. GDB Debugging Introduction GDB is a powerful UNIX-like system for program debugging tools released by the FSF (Free Software Foundation). GDB can be used to do the following: Start the program, you can follow the developer's custom requirements to run the program. Allows the debugged program to stop at the breakpoint set by the developer. (A breakpoint can be a conditional expression) when the program is stopped, you can check what happens in the program at this time. Dynamically change the execution environment of the current program. The GDB version that currently supports the debug Go program must be greater than 7.1. When compiling the Go program, you need to pay attention to the following points to pass the parameters-ldflags "-S", ignoring the debug print message-gcflags "-n-l" parameter, this can be ignored in the go internal optimizations, aggregate variables and functions such as optimization, which is very difficult for gdb debugging, So add these two parameters at compile time to avoid these optimizations. Common commands gdb Common commands are as follows the list Shorthand command L, used to display the source code, the default display of 10 lines of code, followed by the specific line of the parameter display, for example: List 15, showing 10 lines of code, where the 15th line in the display of 10 lines inside the middle, as shown below. Ten time. Sleep (2 * time. Second) One C <-i12}13 Close (c)}15 + func main () {+ msg: = "Starting main", FMT. PRINTLN (msg) Bus: = Make (chan int) The break shorthand command B, used to set the breakpoint, followed by the parameter set the breakpoint line number, for example, B 10 set a breakpoint on line tenth. Delete Shorthand command d, used to delete the breakpoint, followed by the breakpoint set the sequence number, this sequence number can be through the info Breakpoints gets the breakpoint ordinal of the corresponding setting, as shown below is the set breakpoint number that is displayed. Num Type Disp Enb Address what 2 Breakpoint Keep y 0x0000000000400dc3 in Main.main at/home/xiemengjun/gdb.go:23breakpointalready hits 1 Timeba Cktrace shorthand command BT, which is used to print the executed code procedure as follows: #0 Main.main () at/home/xiemengjun/gdb.go:23#1 0x000000000040d61e in Runtime.main () at /home/xiemengjun/go/src/pkg/runtime/proc.c:244#2 0x000000000040d6c1 in Schedunlock () at/home/xiemengjun/go/src/pkg /runtime/proc.c:267#3 0x0000000000000000 in?? () The Infoinfo command is used to display information, followed by several parameters, we commonly used the following: Info locals displays the value of the variable in the currently executing program info breakpoints Displays the list of breakpoints currently set info Goroutines displays a list of currently executed Goroutine, as shown in the following code, with * representing the currently executing * 1 running runtime.gosched* 2 syscall runtime.entersyscall 3 waiting run Time.gosched 4 runnable runtime.goschedprint Shorthand command p, used to print variables or other information, followed by the name of the variable to be printed, and of course some useful functions $len () and $cap (), Used to return the length and capacity of the current string, slices, or maps. Whatis is used to display the type of the current variable, followed by the variable name, such as Whatis msg, which is shown as follows: type = structstringnext shorthand command n, which is used for stepping into the next step, when there is a breakpoint, You can enter N to jump to the next step to continue with the coutinue abbreviation command C, to jump out whenBefore the breakpoint, you can follow the parameter n, skip the number of times the breakpoint set variable the command used to change the value of the variable during the run, such as: Set Variable <var>=<value> The debugging process we use the following code to demonstrate how to debug the Go program through GDB, the following is the code to be demonstrated: Package main import ("FMT" "Time") Func counting (cchan<-int) {fo R 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)}} compiles the file, generates the executable file Gdbfile:go build-gcflags "-n-l" Gdbfile.go starts debugging with gdb command: GDB Gdbfile start after the first to see if this program can be run, as long as the input Run command to enter after the program to start running, the program is normal to see the program output as follows, and we directly execute the program output on the command line is the same: (GDB) Runstartingprogram: /home/xiemengjun/gdbfilestarting MAINCOUNT:0COUNT:1COUNT:2COUNT:3COUNT:4COUNT:5COUNT:6COUNT:7COUNT:8COUNT:9[LWP 2771exited][inferior 1 (Process 2771) exited normally] OK, now that we know how to get the program running, start setting breakpoints on the code: (GDB) BR Main.mainbreakpoint 1 At0x4010b0:file/data/code/gowork/src/my_code/d5.go, line 13. (GDB) BR Main.countingbreakpoint 2 At0x401000:file/data/code/gowork/src/my_code/d5.go, line 6. (GDB) List Main.main time. Sleep (2 * time. Second) c <-i} close (c)} func main () {msg: = "Starting main" Fmt. PRINTLN (msg) Bus: = Make (chan int) msg = "Starting a fo gofunction" (gdb) List main.counting Packa GE main import ("FMT" "Time") Func counting (c chan<-int) {for i:=0;i < 10;i++ {time. Sleep (2 * time. Second) c <-i} (gdb) Runstartingprogram:/home/xiemengjun/gdbfilestarting main[new LWP 3284][SW Itching TOLWP 3284] Breakpoint 1,main.main () at/home/xiemengjun/gdbfile.go:2323 FMT. Println ("Count:", count) above example B 23 indicates that the breakpoint is set on line 23rd, and then enter run to start running the program. Now the program stops at the place where the breakpoint is set, we need to look at the source code of the corresponding context of the breakpoint, enter the list to see the source display starting from the first five lines of the current stop line: (GDB) list18 FMT. PRINTLN (msg) Bus: = Make (chan int) msg = "StartingA Gofunc "Go Counting (bus) for count: = Range Bus {% FMT. Println ("Count:", count) 24}25} now GDB has retained some useful debugging information in the context of running the current program, we just need to print out the corresponding variable to see the type and value of the variable: (gdb) Infolocalscount = 0bu S =0xf840001a50 (GDB) P count$1 = 0 (gdb) p bus$2 = (chan int) 0xf840001a50 (gdb) Whatis bustype = Chan int the next step is to let the program proceed, so keep looking. Polygon Command (GDB) ccontinuing.count:0[new LWP 3303][switching tolwp 3303] Breakpoint 1,main.main () at/home/xiemengjun/gdbfile. Go:2323fmt. Println ("Count:", Count) (GDB) ccontinuing.count:1[switching tolwp 3302] Breakpoint 1,main.main () at/home/xiemengjun/ Gdbfile.go:2323fmt. Println ("Count:", count) executes the code once every time you enter C, and then jumps to the next for loop, continuing to print out the corresponding information. Imagine that you currently need to change the information for context-sensitive variables, skip some processes, and proceed to the next step to get the results you want after the change: (gdb) Info localscount = 2bus =0xf840001a50 (gdb) Set Variable count=9 ( GDB) Info localscount = 9bus =0xf840001a50 (gdb) ccontinuing.count:9[switching tolwp 3302] Breakpoint 1,main.main () at/h Ome/xiemengjun/gdbfile.go:2323fmt. Println ("Count:", count) finally think a little bit about how many goroutine were created in the process before the entire program was run, and each GWhat Oroutine are doing: (GDB) Info goroutines* 1 runningruntime.gosched* 2 syscallruntime.entersyscall3 waitingruntime.gosched4 Runnableruntime.gosched (GDB) goroutine 1 bt#00x000000000040e33b in runtime.gosched () at/home/xiemengjun/go/src/pkg/ runtime/proc.c:927#10x0000000000403091 in Runtime.chanrecv (C=void, Ep=void, selected=void,received=void) at/home/ xiemengjun/go/src/pkg/runtime/chan.c:327#20x000000000040316f in Runtime.chanrecv2 (t=void, c=void) at/home/ xiemengjun/go/src/pkg/runtime/chan.c:420#30x0000000000400d6f in Main.main () at/home/xiemengjun/gdbfile.go:22# 40x000000000040d0c7 in Runtime.main () at/home/xiemengjun/go/src/pkg/runtime/proc.c:244#5 0x000000000040d16ain Schedunlock () at/home/xiemengjun/go/src/pkg/runtime/proc.c:267#60x0000000000000000 in?? () by looking at Goroutines's commands, we can clearly understand how goruntine is executed inside, and the order in which each function is called is plainly displayed. In this section, we introduce some basic commands for GDB to debug the Go program, including run, print, info, set variable, coutinue, list, break and other frequently used debugging commands, through the example above, I believe the reader has a basic understanding of debugging the Go program through GDB, and if you want to get more debugging tips, please refer to the GDB Debug Manual on the official website and the GDB official website manual.