深入講解 Golang 調試利器 Delve

一、前言

     Devle 是一個非常棒的 golang 調試工具,支持多種調試方式,直接運行調試,或者 attach 到一個正在運行中的 golang 程序,進行調試。

  1. 實現類似 Visual Studio 的斷點調試功能

  2. 實現在程序 Crash 的時候生成 Coredump 文件

  3. 實現  Web Server 調試。

1.1 Delve 常用命令

二、安裝

go get -u github.com/go-delve/delve/cmd/dlv

如果你的 go 版本爲 1.5 請先設置環境變量 GO15VENDOREXPERIMENT=1 再運行 go get。

三、調試程序

先寫一個簡單的 web 服務,然後使用 Devle 來進行調試。

package main
import (
  "fmt"
  "log"
  "net/http"
  "os"
)
const port = "8000"
func main() {
  http.HandleFunc("/hi", hi)
  fmt.Println("runing on port: " + port)
  log.Fatal(http.ListenAndServe(":"+port, nil))
}
func hi(w http.ResponseWriter, r *http.Request) {
  hostName, _ := os.Hostname()
  fmt.Fprintf(w, "HostName: %s", hostName)
}

使用 Delve 運行我們的 main.go

dlv debug ./main.go

執行如下:

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

接下來對 main 方法打斷點,如下:

(dlv) b main.main

執行輸出如下:

Breakpoint 1 set at 0xe544ef for main.main() ./src/tes1/main.go:12

然後執行,執行命令如下:

(dlv) c

然後選擇如下命令繼續執行:

  輸入 s 回車,單步執行

  輸入 print(別名 p)輸出變量信息  

  輸入 args 打印出所有的方法參數信息

  輸入 locals 打印所有的本地變量

其他的命令我就不在這裏給大家演示了,自己動動手試一下。

四、調試線上程序

先通過如下命令找到服務運行的進程 id:

ps aux|grep main

輸出結果如下:

使用 Delve 運行調試如下:

dlv attach 29260

接下來對 main 方法打斷點,如下:

b /home/goworkspace/src/github.com/mytest/main.go:20

訪問服務的端口,訪問路徑如下:

curl localhost:8000/hi

然後看一下 dlv 斷點是否執行,結果如下:

如上,我們發現斷點已執行,可以繼續調試之旅。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/iCDNV99Mmn7K1OXJQlYvOw