Note that Delve is a better alternative to GDB when debugging Go programs built with the standard toolchain. It understands the Go runtime, data structures, and expressions better than GDB. Delve currently supports Linux, OSX, and Windows on amd64. For the most up-to-date list of supported platforms, please see the Delve documentation.
GDB does not understand Go programs well. The stack management, threading, and runtime contain aspects that differ enough from the execution model GDB expects that they can confuse the debugger and cause incorrect results even when the program is compiled with gccgo. As a consequence, although GDB can be useful in some situations (e.g., debugging Cgo code, or debugging the runtime itself), it is not a reliable debugger for Go programs, particularly heavily concurrent ones. Moreover, it is not a priority for the Go project to address these issues, which are difficult.
Delve is a debugger for the Go programming language【2】.
(dlv) help The following commands are available: args ------------------------ Print function arguments. break (alias: b) ------------ Sets a breakpoint. breakpoints (alias: bp) ----- Print out info for active breakpoints. call ------------------------ Resumes process, injecting a function call (EXPERIMENTAL!!!) clear ----------------------- Deletes breakpoint. clearall -------------------- Deletes multiple breakpoints. condition (alias: cond) ----- Set breakpoint condition. config ---------------------- Changes configuration parameters. continue (alias: c) --------- Run until breakpoint or program termination. // 继续运行 deferred -------------------- Executes command in the context of a deferred call. disassemble (alias: disass) - Disassembler. down ------------------------ Move the current frame down. edit (alias: ed) ------------ Open where you are in $DELVE_EDITOR or $EDITOR exit (alias: quit | q) ------ Exit the debugger. frame ----------------------- Set the current frame, or execute command on a different frame. funcs ----------------------- Print list of functions. goroutine (alias: gr) ------- Shows or changes current goroutine goroutines (alias: grs) ----- List program goroutines. help (alias: h) ------------- Prints the help message. libraries ------------------- List loaded dynamic libraries list (alias: ls | l) -------- Show source code. // 显示代码 locals ---------------------- Print local variables. next (alias: n) ------------- Step over to next source line. // 单步下一句 on-------------------------- Executes a command when a breakpoint is hit. print (alias: p) ------------ Evaluate an expression. regs ------------------------ Print contents of CPU registers. restart (alias: r) ---------- Restart process. set------------------------- Changes the value of a variable. source ---------------------- Executes a file containing a list of delve commands sources --------------------- Print list of source files. stack (alias: bt) ----------- Print stack trace. step (alias: s) ------------- Single step through program. // 进入函数内,单步下一句 step-instruction (alias: si) Single step a single cpu instruction. stepout (alias: so) --------- Step out of the current function. thread (alias: tr) ---------- Switch to the specified thread. threads --------------------- Print out info for every traced thread. trace (alias: t) ------------ Set tracepoint. types ----------------------- Print list of types up -------------------------- Move the current frame up. vars ------------------------ Print package variables. whatis ---------------------- Prints type of an expression. Type help followed by a command for full documentation.
dlv exec
Execute a precompiled binary, and begin a debug session.
1 2 3 4 5
➜ file ./main ./main: Mach-O 64-bit executable x86_64 ➜ dlv exec ./main Type 'help' for list of commands. (dlv)
dlv attach
Attach to running process and begin debugging.
注意:在退出时,有可选是否要kill该进程。
1 2 3 4
[root@yg-man-uhost-set9-01 ~]# dlv attach 22063 Type'help'for list of commands. (dlv) q Would you like to kill the process? [Y/n] n
(dlv) gr 28239985 Switched from28241159 to 28239985 (thread 31788) (dlv) bt 00x000000000042c76a in runtime.gopark at /usr/local/go/src/runtime/proc.go:272 10x000000000042c84e in runtime.goparkunlock at /usr/local/go/src/runtime/proc.go:277 20x000000000043ce91 in runtime.semacquire at /usr/local/go/src/runtime/sema.go:130 30x000000000043cb74 in sync.runtime_SemacquireMutex at /usr/local/go/src/runtime/sema.go:62 40x000000000046c45d in sync.(*Mutex).Lock at /usr/local/go/src/sync/mutex.go:87 50x0000000000817b1d in uhost-go/uhost-scheduler/logic.updateBuffer at /Users/patrick.xu/go/src/uhost-go/uhost-scheduler/logic/get_suitable_resource.go:418 60x0000000000814bd7 in uhost-go/uhost-scheduler/logic.getSuitableResource at /Users/patrick.xu/go/src/uhost-go/uhost-scheduler/logic/get_suitable_resource.go:328 70x00000000006cecd4 in uframework/task.TCPTaskFunc.ServeTCP at /Users/patrick.xu/go/src/uframework/task/tcp_task_handle.go:27 80x00000000006d02b8 in uframework/task.(*TCPTask).Run.func1 at /Users/patrick.xu/go/src/uframework/task/tcp_task.go:66 90x0000000000458dd1 in runtime.goexit at /usr/local/go/src/runtime/asm_amd64.s:2197
再去看业务代码, frame 5 list
1 2 3
(dlv) frame 5 list Goroutine 28239985 frame 5 at /Users/patrick.xu/go/src/uhost-go/uhost-scheduler/logic/get_suitable_resource.go:418 (PC: 0x817b1d) Command failed: open /Users/patrick.xu/go/src/uhost-go/uhost-scheduler/logic/get_suitable_resource.go: no such file or directory
(gdb) info threads * 1 process 10732runtime.epollwait () at /usr/local/go/src/runtime/sys_linux_amd64.s:560 (gdb) thread apply all bt
Thread 1 (process 10732): #0runtime.epollwait () at /usr/local/go/src/runtime/sys_linux_amd64.s:560 #10x00000000004280d1 in runtime.netpoll (block=true, ~r1=0x1) at /usr/local/go/src/runtime/netpoll_epoll.go:67 #20x0000000000430f8f in runtime.findrunnable (gp#10=0xc42001c000, inheritTime=false) at /usr/local/go/src/runtime/proc.go:2084 #30x0000000000431aec in runtime.schedule () at /usr/local/go/src/runtime/proc.go:2222 #40x0000000000431deb in runtime.park_m (gp=0xc4200011e0) at /usr/local/go/src/runtime/proc.go:2285 #50x000000000045626b in runtime.mcall () at /usr/local/go/src/runtime/asm_amd64.s:269 #60x0000000000cebd00 in runtime.work () #70x00007ffe3162bc70 in ?? () #80x0000000000cebd80 in runtime.work () #90x00007ffe3162bc60 in ?? () #100x000000000042f0e4 in runtime.mstart () at /usr/local/go/src/runtime/proc.go:1149 #110x00000000004560d9 in runtime.rt0_go () at /usr/local/go/src/runtime/asm_amd64.s:169 #120x0000000000000009 in ?? () #130x00007ffe3162bca8 in ?? () #140x0000000000000009 in ?? () #150x00007ffe3162bca8 in ?? () #160x0000000000000000 in ?? ()