這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
安裝gdb
MAC OS X安裝Xcode時,會帶一個6.x版本的gdb,只支援DWARF2。 而Go的編譯檔案預設是包含 DWARFv3 調試資訊,因此需要升級gdb版本到7.1或以上。 安裝步驟:
123456 |
$ curl -O http://ftp.gnu.org/gnu/gdb/gdb-7.3.1.tar.gz$ tar -xzf gdb-3.7.1.tar.gzma$ cd gdb-7.3.1$ ./configure$ make$ [sudo] make install
|
通過上面的步驟安裝完後,gdb7.3 會安裝到/usr/local/bin/gdb
,原來的gdb 6.x在/usr/bin/gdb
。這個時候直接執行gdb,預設使用的還是gdb 6.x(依賴於你的$PATH設定)。如果想顯示調用gdb 7.3就得使用絕對路徑,/usr/local/bin/gdb
。因為我需要用Xcode調試iOS程式,所以要保證gdb 6.x依然可用,否則可以用/usr/local/bin/
下的gdb替換/usr/bin
下面的,這樣每次調用就不需要使用絕對路徑了。
剩下的事情就和作業系統無關了。
使用步驟
1 . 編譯
1 |
$ go build -gcflags "-N -l" test.go 關閉內聯最佳化,便於輸出調試資訊
|
2 . 進入gdb環境
1 |
$ sudo /usr/local/bin/gdb test //預設的gdb是6.X版本,因此要指定路徑
|
3 . 載入golang運行時支援
1 |
(gdb) source /usr/local/go/src/pkg/runtime/runtime-gdb.py
|
4 . gdb下一些調試命令
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748 |
(gdb) l main.main #查看原始碼代碼(gdb) b 50 #設定斷點(gdb) info b #查看斷點資訊 Num Type Disp Enb Address What 1 breakpoint keep y 0x0000000000002239 in main.main at /Users/kenshin/workspace/gogo/test.go:50(gdb) run #運行,直到觸發斷點中斷(gdb) n #繼續執行下一行(gdb) s #進入函數/方法(gdb) info locals #查看局部變數ma err = {tab = 0x0, data = 0xc2000bdfc0}(gdb) info args #查看參數 s = 0xc2000b6f00 addr = "0.0.0.0:8000"(gdb) help info (gdb) p addr #列印變數 $6 = "0.0.0.0:8000"(gdb) c #繼續執行,直到下一個斷點(gdb) whatis s #查看變數類型 type = struct github.com/hoisie/web.Server *(gdb) where/bt #查看堆棧資訊,判斷函數調用關係 #0 net.resolveInternetAddr (net="udp4") at /usr/local/go/src/pkg/net/ipsock.go:164 #1 in net.ResolveUDPAddr (net="udp4") at /usr/local/go/src/pkg/net/udpsock.go:45 #2 in main.SocketListen (ip="127.0.0.1") at /Users/kenshin/workspace/gor/test.go:13(gdb) up #回到上一層調用函數 #0 in net.ResolveUDPAddr (net="udp4") at /usr/local/go/src/pkg/net/udpsock.go:45 #1 in main.SocketListen (ip="127.ma0.0.1") at /Users/kenshin/workspace/gor/test.go:13(gdb) down #再進入下一層函數 #0 net.resolveInternetAddr (net="udp4") at /usr/local/go/src/pkg/net/ipsock.go:164 #1 in net.ResolveUDPAddr (net="udp4") at /usr/local/go/src/pkg/net/udpsock.go:45 #2 in main.SocketListen (ip="127.0.0.1") at /Users/kenshin/workspace/gor/test.go:13(gdb) shell #輸入shell,可以進入到shell,輸入exit退出shell回到gdb環境 bash-3.2# exit
|
有一點需要特別說明的:gdb對slices, arrays 和 strings這些golang的資料類型支援不是很好,例如p str顯示的是一個map類型的資料
123456 |
(gdb) p r # r string := "process"$16 = {str = 0x2f0170 "process", len = 7} (gdb) p r-> #可以通過`TAB`獲得一些提示len str(gdb) p r->str $17 = (uint8 *) 0x2f0170 "process"
|
現在直接通過gdb來調試golang還不是非常好用,輸出的調試資訊閱讀困難,goroutine內的棧資訊更是沒法跟蹤。
現在圍繞go的開源項目這麼多,希望很快就會有類似ipdb這樣的東西出來。
更多gdb命令參考 :http://golang.org/doc/gdb