go runtime debug 小技巧
前言
本意是打算研究一下go程序的啟動流程,然后就去網(wǎng)上搜索了一下入門教程。結(jié)果令我有點沮喪,搜到的幾乎所有文章開篇都是通過GDB調(diào)試, 然后就是不同平臺下的匯編代碼。。。
這令我很不開心, 雖然C/C++應(yīng)用很廣泛, 但是我對它真的沒啥興趣啊, 對它相關(guān)的調(diào)試工具就更加不感冒了, 雖然它可以調(diào)試go程序, 但是總感覺心里少了點什么, 難道dlv它不香嘛, 于是就有了今天這篇文章。
dlv命令行debug
dlv的名頭應(yīng)該不用我多說, 所以我們直奔主題
1. 開始debug
dlv debug test.go
執(zhí)行上述命令后, 就會進入debug交互命令行界面, 在這個界面任何時候輸入h都會打印幫助信息.
2. 增加函數(shù)斷點
交互界面輸入下面命令后,會在main包下的main函數(shù)打上一個斷點
b main.main
3. 指定行斷點
在test.go的文件第6行打上一個斷點
b test.go:6
4. 開始執(zhí)行

如上圖所示, 我們繼續(xù)執(zhí)行時會發(fā)現(xiàn)=>會停留在我們前面標(biāo)記的斷點處。這里的其他命令我們在本篇文章不做過多的介紹了, 我們盡量緊扣本篇的主題。
5. 打印調(diào)用棧

如上圖所示, 我們通過dlv的調(diào)用棧可以看見調(diào)用main函數(shù)之前,還執(zhí)行了asm_amd64.s(本次debug的機器為mac)的匯編代碼和proc.go的main函數(shù)。
意外之喜, 本來只是單純的不想用GDB調(diào)試去了解go程序的啟動流程, 現(xiàn)在卻也有了一些頭緒, 下面我們繼續(xù)本篇的主題。
1. 在runtime包中標(biāo)記斷點并開始調(diào)試

綜上: 按照上面的步驟, 我們通過dlv就可以進行runtiime的調(diào)試, 并且還可以了解go程序的啟動流程。
vscode圖形化debug
我個人比較喜歡用vscode進行代碼編輯, 所以在擼go的時候用的也是vscode, 體驗還是非常不錯的。
關(guān)于vscode如何配置go的開發(fā)環(huán)境和配置圖形化debug就不再本篇過多贅述, 筆者在這里分享一下自己在vscode中關(guān)于go的配置。

1. 打斷點
本部分在備用電腦上面完成,go版本為: go1.14.2

此次直接復(fù)用了前面文章你能一口說出go中字符串轉(zhuǎn)字節(jié)切片的容量嘛?的demo。三個斷點分別位于,main/test.go, runtime/proc.go和runtime/string.go.
2. 運行
vscode通過F5快捷鍵即可快速開始debug

接下來, 你就可以開始快樂的debug之旅啦
debug不出現(xiàn)在call stack的函數(shù)
細心的同學(xué)肯定已經(jīng)發(fā)現(xiàn)了,在上面vscode圖形化debug的調(diào)用棧里面并沒有runtime/string.go的影子。接下來, 我們結(jié)合本篇的主題繼續(xù)往下分析
相信看過我切片真的是引用類型嘛?這篇文章的同學(xué),心里已經(jīng)基本有數(shù)了。對于這種即沒有調(diào)用棧也沒有明確調(diào)用者的函數(shù), 我們遵循以下兩點即可完成對它的debug
1. 首先查看其匯編代碼
go tool compile -N -l -S test.go
關(guān)鍵匯編代碼如下:

如上圖所示,我們發(fā)現(xiàn)了stringtoslicebyte函數(shù), 這樣我們就可以打斷點了, 只要打上了斷點就可以快樂的調(diào)試了
2. runtime函數(shù)打斷點時機
部分rumtime函數(shù)打好斷點后, debug程序會無法啟動, 這個時候就需要延遲打點(“延遲打點”為筆者自己總結(jié)的名字)了。
首先,在main函數(shù)的入口處打一個斷點(調(diào)用runtime函數(shù)之前的斷點均可),刪除runtime函數(shù)的斷點。
最后, 等待debug程序啟動了,再給runtime函數(shù)打上斷點即可。
至此, 祝各位開啟快樂的debug之旅。
本文來自 GoCN 原創(chuàng)投稿,點擊“閱讀原文”查看作者博客
