dlv工具使用
dlv工具使用
注意!golang无法在mac系统下生成coredump文件!
注意!golang无法在mac系统下生成coredump文件!
注意!golang无法在mac系统下生成coredump文件!
后面会解释原因传送门
coredump的定义
百科定义
核心转储是操作系统在进程收到某些信号而终止运行时,将此时进程地址空间的内容以及有关进程状态的其他信息写入一个磁盘文件。这种信息往往用于调试。
coredump文件可以帮助我们定位bug,特别是程序由于偶现的问题而崩溃的时候
而dlv正是在golang下的一种用于分析coredump文件的命令行工具
用处
在开发go的应用时,使用如goland之类的ide,一般是支持debug功能,在图形界面的操作下,debug操作比较简单。
在测试环境甚至线上环境中,已经打包的代码调试起来是很不方便的。
dlv是一种专门服务于golang的代码debug工具,通过命令行来实现代码的断点、单步调试等功能
对于panic的情况,可能没有足够的日志来追踪出现问题的模块,这时可以使用dlv core命令来查看系统崩溃产生的coredump文件来分析
安装
$ git clone https://github.com/go-delve/delve
$ cd delve
$ go install github.com/go-delve/delve/cmd/dlv@latest
命令简介
命令行中执行help命令可以看到dlv的帮助文档,可以通过attach、core、debug、test等方式来开启调试。
具体的命令参数,可以使用dlv help [command] 来查看
$ dlv help
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 with a terminal client.
core Examine a core dump.
dap Starts a headless 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 via JSON-RPC or DAP.
--allow-non-terminal-interactive Allows interactive sessions of Delve that don't have a terminal as stdin, stdout and stderr
--api-version int Selects JSON-RPC API version when headless. New clients should use v2. Can be reset via RPCServer.SetApiVersion. See Documentation/api/json-rpc/README.md. (default 1)
--backend string Backend selection (see 'dlv help backend'). (default "default")
--build-flags string Build flags, to be passed to the compiler. For example: --build-flags="-tags=integration -mod=vendor -cover -v"
--check-go-version Exits if the version of Go in use is not compatible (too old or too new) with the version of Delve. (default true)
--disable-aslr Disables address space randomization
--headless Run debug server only, in headless mode. Server will accept both JSON-RPC or DAP client connections.
-h, --help help for dlv
--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)
-r, --redirect stringArray Specifies redirect rules for target process (see 'dlv help redirect')
--wd string Working directory for running the program.
Additional help topics:
dlv backend Help about the --backend flag.
dlv log Help about logging flags.
dlv redirect Help about file redirection.
Use "dlv [command] --help" for more information about a command.
当前,我们主要针对测试/线上环境的debug做深入了解
dlv core命令
coredump的生成
1、操作系统的支持
取消core file大小限制
$ ulimit -a # 查看core file大小
$ ulimit -c unlimited # 取消core file大小限制
2、开启coredump
$ sysctl -a | grep core # 查看系统core相关配置
kern.corefile: /cores/core.%N.%P # 标识coredump文件位置
kern.coredump: 1
kern.sugid_coredump: 0
machdep.cpu.core_count: 8
machdep.cpu.cores_per_package: 8
$ sudo sysctl kern.coredump=1 # 开启coredump
kern.coredump: 0 -> 1
3、golang环境支持
当程序崩溃时,golang有对应的环境变量可以开启控制错误的打印粒度
$ export GOTRACEBACK=crash
对应GOTRACEBACK的全部枚举值以及含义如下
- none,不显示任何 goroutine 堆栈信息
- single,默认级别,显示当前 goroutine 堆栈信息
- all,显示所有 user (不包括 runtime)创建的 goroutine 堆栈信息
- system,显示所有 user + runtime 创建的 goroutine 堆栈信息
- crash,和 system 打印一致,但会生成 core dump 文件(Unix 系统上,崩溃会引发 SIGABRT 以触发core dump)
使用dlv分析coredump文件
$ cd /your/可执行程序所在/path/
$ dlv core [打包后端可执行程序] [/your/coredump/path/filename]
Type 'help' for list of commands.
(dlv)
这时即可开启dlv来debug代码,使用help命令可以查看命令文档
Type 'help' for list of commands.
(dlv) help
The following commands are available:
Running the program:
call ------------------------ Resumes process, injecting a function call (EXPERIMENTAL!!!)
continue (alias: c) --------- Run until breakpoint or program termination.
next (alias: n) ------------- Step over to next source line.
rebuild --------------------- Rebuild the target executable and restarts it. It does not work if the executable was not built by delve.
restart (alias: r) ---------- Restart process.
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.
Manipulating breakpoints:
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.
on --------------------- Executes a command when a breakpoint is hit.
toggle ----------------- Toggles on or off a breakpoint.
trace (alias: t) ------- Set tracepoint.
watch ------------------ Set watchpoint.
Viewing program variables and memory:
args ----------------- Print function arguments.
display -------------- Print value of an expression every time the program stops.
examinemem (alias: x) Examine raw memory at the given address.
locals --------------- Print local variables.
print (alias: p) ----- Evaluate an expression.
regs ----------------- Print contents of CPU registers.
set ------------------ Changes the value of a variable.
vars ----------------- Print package variables.
whatis --------------- Prints type of an expression.
Listing and switching between threads and goroutines:
goroutine (alias: gr) -- Shows or changes current goroutine
goroutines (alias: grs) List program goroutines.
thread (alias: tr) ----- Switch to the specified thread.
threads ---------------- Print out info for every traced thread.
Viewing the call stack and selecting frames:
deferred --------- Executes command in the context of a deferred call.
down ------------- Move the current frame down.
frame ------------ Set the current frame, or execute command on a different frame.
stack (alias: bt) Print stack trace.
up --------------- Move the current frame up.
Other commands:
config --------------------- Changes configuration parameters.
disassemble (alias: disass) Disassembler.
dump ----------------------- Creates a core dump from the current process state
edit (alias: ed) ----------- Open where you are in $DELVE_EDITOR or $EDITOR
exit (alias: quit | q) ----- Exit the debugger.
funcs ---------------------- Print list of functions.
help (alias: h) ------------ Prints the help message.
libraries ------------------ List loaded dynamic libraries
list (alias: ls | l) ------- Show source code.
source --------------------- Executes a file containing a list of delve commands
sources -------------------- Print list of source files.
transcript ----------------- Appends command output to a file.
types ---------------------- Print list of types
Type help followed by a command for full documentation.
golang无法在mac系统下生成coredump
这里是go语言本身的限制,当系统为darwin且属于amd64架构时,不会生成coredump文件
如果有mac的m1/m2芯片(m芯片属于arm架构)的同学,可以试试,欢迎告知结论
$ go version
go version go1.18.2 darwin/amd64
$ vim runtime/signal_unix.go +993
//go:nosplit
func crash() {
// OS X core dumps are linear dumps of the mapped memory,
// from the first virtual byte to the last, with zeros in the gaps.
// Because of the way we arrange the address space on 64-bit systems,
// this means the OS X core file will be >128 GB and even on a zippy
// workstation can take OS X well over an hour to write (uninterruptible).
// Save users from making that mistake.
if GOOS == "darwin" && GOARCH == "amd64" {
return
}
dieFromSignal(_SIGABRT)
}