調試程序是程序猿的一項必備技能,有多種手段來調試程序,如打印控制檯輸出,查看日誌,以及設置斷點,使用debug做單步跟蹤進去調試。這篇文章主要從go使用debug爲題進行展開。
GDB
介紹
GDB是GNU開源組織發佈的一個強大的UNIX下的程序調試工具。 在mac上安裝,會有認證方面的問題,查了一些資料,沒能解決,就放棄了。使用vagrant搭建了一個go的環境並安裝了gdb工具,在需要使用gdb時,通常是將代碼通過vagrant目錄映射到linux虛擬主機中,然後進行GDB調試。這種用的也不是很多,一般主要使用GDB提供的x命令,查看下內存的值。
debug目標
- 設置斷點
- 查看變量值的輸出
- 查看變量內存地址
- 查看變量內存值
- 修改變量的值
基於以上四點,我們通過程序來展示gdb的基本用法
gdb用法
示例程序:
package main
import (
"fmt"
"os"
)
func main() {
fmt.Println("go debug.....")
// 命令參數使用
var argc = len(os.Args)
var argv = append([]string{}, os.Args...)
fmt.Printf("argc:%d\n", argc)
fmt.Printf("argv:%v\n", argv)
// 查看變量內存地址及值
var aa = 1
var bb = -1
fmt.Println(aa)
fmt.Println(bb)
}
- 編譯程序
go build -gcflags="-N -l" demo.go // -N -l用於關閉編譯器的內聯優化
- 啓動gdb
gdb demo
- 設置斷點break
(gdb) b main.main
Breakpoint 1 at 0x488e60: file /home/vagrant/godemo/demo01/demo.go, line 8.
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000488e60 in main.main at /home/vagrant/godemo/demo01/demo.go:8
(gdb)
啓動程序run
(gdb) run arg1 agr2
Starting program: /home/vagrant/godemo/demo01/demo arg1 agr2
[New LWP 5976]
[New LWP 5977]
[New LWP 5978]
Thread 1 "demo" hit Breakpoint 1, main.main () at /home/vagrant/godemo/demo01/demo.go:8
8 func main() {
(gdb)
查看代碼
(gdb) l
4 "fmt"
5 "os"
6 )
7
8 func main() {
9 fmt.Println("go debug.....")
10 // 命令參數使用
11 var argc = len(os.Args)
12 var argv = append([]string{}, os.Args...)
13 fmt.Printf("argc:%d\n", argc)
(gdb)
14 fmt.Printf("argv:%v\n", argv)
15
16 // 查看變量內存地址及值
17 var aa = 1
18 var bb = -1
19
20 fmt.Println(aa)
21 fmt.Println(bb)
22 }
(gdb)
單步執行next
(gdb) n
go debug.....
11 var argc = len(os.Args)
(gdb) n
12 var argv = append([]string{}, os.Args...)
(gdb) n
13 fmt.Printf("argc:%d\n", argc)
(gdb) n
argc:3
14 fmt.Printf("argv:%v\n", argv)
(gdb) n
argv:[/home/vagrant/godemo/demo01/demo arg1 agr2]
打印命令p
打印格式
x 按十六進制格式顯示變量。
d 按十進制格式顯示變量。
u 按十六進制格式顯示無符號整型。
o 按八進制格式顯示變量。
t 按二進制格式顯示變量。
a 按十六進制格式顯示變量。
c 按字符格式顯示變量。
f 按浮點數格式顯示變量。
17 var aa = 1
(gdb) n
18 var bb = -1
(gdb) p aa
$1 = 1
(gdb) p &aa
$2 = (int *) 0xc00007ce40
(gdb) p/x aa
$3 = 0x1
查看內存值命令x
x/<n/f/u> <addr>
n、f、u是可選的參數。
n 是一個正整數,表示顯示內存的長度
f 表示顯示的格式,參見上面
u 表示字節數,GDB默認是4個bytes。
b表示單字節
h表示雙字節
w表示四字節
g表示八字節
<addr>表示一個內存地址
(gdb) p &aa
$2 = (int *) 0xc00007ce40
(gdb) x/1dg 0xc00007ce40
0xc00007ce40: 1
(gdb)
設置值命令
(gdb) set aa = 2
(gdb) p aa
$4 = 2
(gdb)
程序調用棧bt
顯示goroutines
info goroutines // 顯示當前執行的goroutine列表,如下代碼所示,帶*的表示當前執行的
查看變量類型
whatis
這裏只列出出來了一些基本的用法,gdb很強大,還有很多命令,可以深入程序執行的底層,通過以上幾個命令,可以完成一個程序的基本調試。
delve
delve是專爲go語言打造的debug工具,現在的一些IDE工具的debug功能就是基於這個實現的。
啓動debug服務
dlv debug demo.go
其它的命令同gdb大體相同,初級的調試,高級的使用功能,還未深入研究,另外它還可以attach到一個運行的程序進行debug。
IDE工具
如果不習慣使用命令行,可以使用集成開發工具goland,這個帶有圖形化界面操作的debug工具,操作起來比較方便。
喜歡請關注“雲端漫記", 持續爲你更新