Golang debug 推荐使用 Delve 工具,项目地址:https://github.com/derekparker/delve
一、安装
go mod
1. 拉取最新 delve 项目代码到本地,编译安装。
# cd $GOPATH/src/
# git clone https://github.com/derekparker/delve.git
# cd delve/cmd/dlv/
# go build
# go install
go build
go: golang.org/x/crypto@v0.0.0-20180614174826-fd5f17ee7299: unrecognized import path "golang.org/x/crypto" (https fetch: Get https://golang.org/x/crypto?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)
go: golang.org/x/sys@v0.0.0-20180614134839-8883426083c0: unrecognized import path "golang.org/x/sys" (https fetch: Get https://golang.org/x/sys?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)
go: golang.org/x/arch@v0.0.0-20171004143515-077ac972c2e4: unrecognized import path "golang.org/x/arch" (https fetch: Get https://golang.org/x/arch?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)
go.mod
替换:
golang.org/x/arch v0.0.0-20171004143515-077ac972c2e4 => github.com/golang/arch v0.0.0-20171004143515-077ac972c2e4
golang.org/x/crypto v0.0.0-20180614174826-fd5f17ee7299 => github.com/golang/crypto v0.0.0-20180614174826-fd5f17ee7299
golang.org/x/sys v0.0.0-20180614134839-8883426083c0 => github.com/golang/sys v0.0.0-20180614134839-8883426083c0
然后重新编译安装,没有报错则成功。
$GOPATH/bindlv
$ dlv
Delve is a source level debugger for Go programs.
Delve enables you to interact with your program by controlling the execution of the process,
evaluating variables, and providing information of thread / goroutine state, CPU register state and more.
The goal of this tool is to provide a simple yet powerful interface for debugging Go programs.
Pass flags to the program you are debugging using `--`, for example:
`dlv exec ./hello -- server --config conf/config.toml`
Usage:
dlv [command]
Available Commands:
attach Attach to running process and begin debugging.
connect Connect to a headless debug server.
core Examine a core dump.
dap [EXPERIMENTAL] Starts a TCP server communicating via Debug Adaptor Protocol (DAP).
debug Compile and begin debugging main package in current directory, or the package specified.
exec Execute a precompiled binary, and begin a debug session.
help Help about any command
run Deprecated command. Use 'debug' instead.
test Compile test binary and begin debugging program.
trace Compile and begin tracing program.
version Prints version.
Flags:
--accept-multiclient Allows a headless server to accept multiple client connections.
--api-version int Selects API version when headless. (default 1)
--backend string Backend selection (see 'dlv help backend'). (default "default")
--build-flags string Build flags, to be passed to the compiler.
--check-go-version Checks that the version of Go in use is compatible with Delve. (default true)
--headless Run debug server only, in headless mode.
--init string Init file, executed by the terminal client.
-l, --listen string Debugging server listen address. (default "127.0.0.1:0")
--log Enable debugging server logging.
--log-dest string Writes logs to the specified file or file descriptor (see 'dlv help log').
--log-output string Comma separated list of components that should produce debug output (see 'dlv help log')
--only-same-user Only connections from the same user that started this instance of Delve are allowed to connect. (default true)
--wd string Working directory for running the program. (default ".")
Additional help topics:
dlv backend Help about the --backend flag.
dlv log Help about logging flags.
Use "dlv [command] --help" for more information about a command.
二、使用 Delve 调试程序
dlvdlv --help
(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.
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.
disassemble (alias: disass) - Disassembler.
down ------------------------ Move the current frame down.
exit (alias: quit | q) ------ Exit the debugger.
frame ----------------------- Set the current frame, or execute command...
funcs ----------------------- Print list of functions.
goroutine ------------------- Shows or changes current goroutine
goroutines ------------------ List program goroutines.
help (alias: h) ------------- Prints the help message.
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...
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 --------------------- 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)
dlv [command] --helpdlv debug --help
$ dlv debug --help
Compiles your program with optimizations disabled, starts and attaches to it.
By default, with no arguments, Delve will compile the 'main' package in the
current directory, and begin to debug it. Alternatively you can specify a
package name and Delve will compile that package instead, and begin a new debug
session.
Usage:
dlv debug [package] [flags]
Flags:
--continue Continue the debugged process on start.
--output string Output path for the binary. (default "./__debug_bin")
--tty string TTY to use for the target program
Global Flags:
--accept-multiclient Allows a headless server to accept multiple client connections.
--api-version int Selects API version when headless. (default 1)
--backend string Backend selection (see 'dlv help backend'). (default "default")
--build-flags string Build flags, to be passed to the compiler.
--check-go-version Checks that the version of Go in use is compatible with Delve. (default true)
--headless Run debug server only, in headless mode.
--init string Init file, executed by the terminal client.
-l, --listen string Debugging server listen address. (default "127.0.0.1:0")
--log Enable debugging server logging.
--log-dest string Writes logs to the specified file or file descriptor (see 'dlv help log').
--log-output string Comma separated list of components that should produce debug output (see 'dlv help log')
--only-same-user Only connections from the same user that started this instance of Delve are allowed to connect. (default true)
--wd string Working directory for running the program. (default ".")
3. 调试程序
deferdefer.go
package main
import (
"log"
)
var first = "panic in defer"
var second = "panic in main"
func main() {
defer func() {
for {
if err := recover(); err != nil {
log.Println(err)
}else{
log.Fatalln("fatal")
}
}
}()
defer func() {
panic(first)
}()
panic(second)
}
dlv debug defer.go
$ dlv debug defer.go
Type 'help' for list of commands.
(dlv)
命令为break(简:b)b main.go:10
(dlv) b main.main
Breakpoint 1 set at 0x10ae9b8 for main.main() ./main.go:10
breakpoints(简:bp)
(dlv) bp
Breakpoint runtime-fatal-throw at 0x437ef0 for runtime.fatalthrow() c:/go/src/runtime/panic.go:1162 (0)
Breakpoint unrecovered-panic at 0x437f70 for runtime.fatalpanic() c:/go/src/runtime/panic.go:1189 (0)
print runtime.curg._panic.arg
Breakpoint 1 at 0x4cdaff for main.main() C:/Users/y30002195/Desktop/已完成/0.总结文档/go/ch1/4_delve/defer.go:10 (0)
可以看到除了我们手动打的断点,Go 还自动帮我们打了 fatal 异常的两个断点
vars 命令可以查看全部包级的变量:
(dlv) vars main
runtime.main_init_done = chan bool nil
runtime.mainStarted = false
main.second = "panic in main"
main.first = "panic in defer"
命令为continue(简:c)
> main.main() C:/Users/y30002195/Desktop/已完成/0.总结文档/go/ch1/4_delve/defer.go:10 (hits goroutine(1):1 total:1) (PC: 0x4cdaff)
5: )
6:
7: var first = "panic in defer"
8: var second = "panic in main"
9:
=> 10: func main() {
11: defer func() {
12: for {
13: if err := recover(); err != nil {
14: log.Println(err)
15: }else{
received SIGINT, stopping process (will not forward signal)
next(简:n)
6:
7: var first = "panic in defer"
8: var second = "panic in main"
9:
10: func main() {
=> 11: defer func() {
12: for {
13: if err := recover(); err != nil {
14: log.Println(err)
15: }else{
16: log.Fatalln("fatal")
argslocals
args
(no args)
locals
(no locals)
该程序没有局部变量,所以没有相关参数信息
stack
stack
0 0x00000000004cdb16 in main.main
at C:/Users/y30002195/Desktop/已完成/0.总结文档/go/ch1/4_delve/defer.go:11
1 0x000000000043a40a in runtime.main
at c:/go/src/runtime/proc.go:203
2 0x0000000000464b21 in runtime.goexit
at c:/go/src/runtime/asm_amd64.s:1373
goroutine/goroutines
goroutine
Thread 14264 at C:/Users/y30002195/Desktop/已完成/0.总结文档/go/ch1/4_delve/defer.go:11
Goroutine 1:
Runtime: C:/Users/y30002195/Desktop/已完成/0.总结文档/go/ch1/4_delve/defer.go:11 main.main (0x4cdb16)
User: C:/Users/y30002195/Desktop/已完成/0.总结文档/go/ch1/4_delve/defer.go:11 main.main (0x4cdb16)
Go: c:/go/src/runtime/asm_amd64.s:220 runtime.rt0_go (0x46289c)
Start: c:/go/src/runtime/proc.go:113 runtime.main (0x43a250)
quit/exit
q
y30002195@DESKTOP-GT8J20C MINGW64 ~/Desktop/已完成/0.总结文档/go/ch1/4_delve