【golang的gdb之dlv】

众所周知gdb是调试c非常好用的一款软件,当然也可以调试golang的二进制文件。不过今天的主角并不是gdb,而是dlv,和gdb类似,也是具有断点调试,输出变量的一系列的功能。

安装

安装方式一:

$ git clone https://github.com/go-delve/delve
$ cd delve
$ go install github.com/go-delve/delve/cmd/dlv

安装方式二

(适用于Go 1.16及以后版本)
$ go install github.com/go-delve/delve/cmd/dlv@latest
执行完命令后,dlv命令被安装在 GOPATH/bin目录下。如果没有设置GOPATH,则被默认安装在$HOME/go/bin目录下。

输入dlv命令检查是否安装成功:

$ dlv version
Delve Debugger
Version: 1.8.3
Build: $Id: f92bb46b82b3b92d79ce59c4b55eeefbdd8d040c $

使用

基于pid

这种是通常已经跑的进程。命令 dlv attach pid.
这里写了一个死循环每一秒输出一个hello,让进程不会退出

package main

import (
	"fmt"
	"time"
)

func main() {
	var a interface{}
	a = 1

	if a != nil {
		for {
			fmt.Println("hello")
			time.Sleep(1 * time.Second)
		}
	}

}

然后go run main.go运行起来。通过 ps -ef | grep main 找到这个进程id。
在这里插入图片描述
可以看到这个pid是31164。
于是通过 dlv attach 31164进行交互,如图:
在这里插入图片描述
这样就进入了调试模式,关于哪些命令和dlv debug模式一起说。

基于main文件

就是程序还未启动,直接用dlv去启动并调试程序,命令: dlv debug main.go.这里就是把go run 换成 dlv debug后,就可以进入到交互模式,如图:
在这里插入图片描述

常用命令

运行程序

 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.

这里用的比较多的是c,n,s.这三个命令。下面来举个例子。

continue

如下在fmt.Println这里打了一个断点:
在这里插入图片描述
然后执行continue,也就是c,可见执行完了输出hello,又到了下一个断点。
在这里插入图片描述

next

next解释是 Step over to next source line.也就是执行到下一个代码行。
在这里插入图片描述
可见分别是14行和15行,也就是执行到下一个代码行

step

官方解释是Single step through program。就是进入到下一个代码行,但是和next不同的是,会进入下一个代码执行的地方.如图执行到了fmt.Println(“hello”)这里,源码是在/usr/local/go/src/fmt/print.go 中273行。
在这里插入图片描述

打断点

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.

break

缩写是b,也就是打断点。需要记住的是这个打断点不仅可以在自己程序里面打断点,
在自己程序里面打。指定包名称和方法名称和行号,如图。这个main是当前main包。然后后面一个main是方法名称,4是行号,在整个文件中在14行。
在这里插入图片描述
同时这个也可以打源码中的断点,runtime就是go官方包的runtime包,如图:
在这里插入图片描述
/usr/local/go/src/runtime/proc.go中的main就是go的g0线程执行的main,并在这个里面初始化了gc等一系列操作。

breakpoints

breakpoints显示有哪些断点,如图
在这里插入图片描述

clear

清楚断点,这里是的值是breakpoints的名称。
在这里插入图片描述
这里的1就是breakpoints中的名称如图
在这里插入图片描述

clearall

清楚所有的断点

查看程序内存和变量

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.

args

输出方法的参数。这里走到Println这个方法这里,a是输入的变量,n和err是返回的,因为被提前初始化了,所以也输出了出来。
在这里插入图片描述

locals

输出本地的变量,就是当前栈上的变量,如图,上面定义了一个a变量类型为interface,值为1。
在这里插入图片描述

print

这个可以输出当前环境的变量,比如之前定义的a变量
在这里插入图片描述
和break可以打go源码包中断点一样,p一样可以输出源码中的变量。
比如这里输出go里面的最大process数量。
在这里插入图片描述

vars

这个是输出当前包下面所有的包变量,包括源码中的变量。
在这里插入图片描述

线程切换


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.

goroutine

查看或者切换到指定的goroutines.可以看到当前上下文
在这里插入图片描述

goroutines

可以看到所有的goroutines的所处状态
在这里插入图片描述

thread

threads

输出线程所处状态
在这里插入图片描述

查看堆栈

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.

stack

这个主要就是为了输出当前的堆栈
在这里插入图片描述

其他命令

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

版权声明:本文为qq_37674060原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。