日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

是否要运行此应用程序_使用Delve调试Go应用程序

發布時間:2023/12/10 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 是否要运行此应用程序_使用Delve调试Go应用程序 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

調試器

任何編程語言中最簡單的調試形式是使用打印語句或日志來寫入標準輸出。這肯定沒有問題,但是當我們的應用程序規模增加并且邏輯變得更加復雜時,這種方式變得極其困難。將打印語句添加到應用程序的每個代碼路徑并不容易。這是調試器派上用場的地方。調試器可幫助我們使用斷點和許多其他功能來跟蹤程序的執行路徑。Delve是Go的一種此類調試器。在本教程中,我們將學習如何使用Delve調試Go應用程序。

安裝Delve

首先請確保您位于一個不包含go.mod文件的目錄中。我比較喜歡我的Documents目錄。

cd ~/Documents/

接下來,讓我們設置GOBIN環境變量。此環境變量指定Delve二進制文件的安裝位置。如果GOBIN已經設置,請跳過此步驟。您可以通過運行以下命令檢查是否設置了GOBIN。

go env | grep GOBIN

如果以上命令顯示GOBIN="",則表示GOBIN未設置。請運行export GOBIN=~/go/bin/命令設置GOBIN。

讓我們通過運行添加GOBIN到PATH export PATH=$PATH:~/go/bin

對于macOS,需要使用Xcode命令行開發人員工具來運行Delve。請運行xcode-select --install以安裝命令行工具。Linux用戶可以跳過此步驟。

現在我們開始安裝Delve。請運行

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

安裝delve。運行此命令后,請通過運行來測試安裝dlv version。成功安裝后,它將打印Delve的版本。

Delve Debugger Version: 1.4.0 Build: $Id: 67422e6f7148fa1efa0eac1423ab5594b223d93b

開始使用Delve

讓我們編寫一個簡單的程序,然后使用Delve開始對其進行調試。

讓我們使用以下命令為示例程序創建目錄。

mkdir ~/Documents/debugSample

在我們剛剛創建的目錄內創建一個文件main.go,內容如下。

package mainimport ( "fmt")func main() { arr := []int{101, 95, 10, 188, 100} max := arr[0] for _, v := range arr { if v > max { max = v } } fmt.Printf("Max element is %d", max)}

上面的程序將打印切片arr的最大元素。運行上面的程序將輸出

Max element is 188

現在我們準備調試程序。讓我們轉到debugSample目錄cd ~/Documents/debugSample。之后,鍵入以下命令以啟動Delve。

dlv debug

上面的命令將開始調試當前目錄中的main軟件包。鍵入上面的命令后,您可以看到終端已更改為(dlv)提示。如果您看到此更改,則表明調試器已成功啟動并等待我們的命令:)。

讓我們啟動第一個命令。

在dlv提示符下,鍵入continue。

(dlv) continue

該continue命令將運行程序,直到出現斷點或程序完成為止。由于我們沒有定義任何斷點,因此該程序將一直運行到完成。

Max element is 188 Process 1733 has exited with status 0

如果看到以上輸出,則調試器已運行,程序已完成:)。但這對我們沒有任何用處。讓我們繼續添加幾個斷點,并觀察調試器如何發揮作用。

創建斷點

斷點在指定的行處暫停程序的執行當執行暫停時,我們可以將命令發送到調試器以打印變量的值,查看程序的堆棧跟蹤,等等。

下面提供了創建斷點的語法

(dlv) break filename:lineno

上面的命令將在filename文件中的lineno行創建一個斷點。

讓我們在行號上添加一個斷點。我們的main.go第9行

(dlv) break main.go:9

運行上述命令后,您將看到輸出Process 1733 has exited with status 0。實際上沒有添加斷點。這是因為continue當時沒有斷點,所以我們在較早運行時就退出了程序。讓我們重新啟動程序,然后嘗試再次設置斷點。

(dlv) restartProcess restarted with PID 2028 (dlv) break main.go:9Breakpoint 1 set at 0x10c16e4 for main.main() ./main.go:9

該restart命令重新啟動程序,然后該break命令設置斷點。上面的輸出確認斷點1設置在main.go中的第9行。

現在讓continue為我們繼續程序,并檢查調試器是否在斷點處暫停程序。

(dlv) continue> main.main() ./main.go:9 (hits goroutine(1):1 total:1) (PC: 0x10c16e4) 4: "fmt" 5: ) 6: 7: func main() { 8: arr := []int{101, 95, 10, 188, 100}=> 9: max := arr[0] 10: for _, v := range arr { 11: if v > max { 12: max = v 13: } 14: }

continue執行完之后,我們可以看到調試器已在第9行暫停了我們的程序。

列出斷點

(dlv) breakpoints

上面的命令列出了應用程序的當前斷點。

(dlv) breakpointsBreakpoint runtime-fatal-throw at 0x102de10 for runtime.fatalthrow() /usr/local/Cellar/go/1.13.7/libexec/src/runtime/panic.go:820 (0) Breakpoint unrecovered-panic at 0x102de80 for runtime.fatalpanic() /usr/local/Cellar/go/1.13.7/libexec/src/runtime/panic.go:847 (0) print runtime.curg._panic.argBreakpoint 1 at 0x10c16e4 for main.main() ./main.go:9 (1)

您可能會驚訝地發現,除了我們添加的斷點之外,還有另外兩個斷點。delve會添加其他兩個斷點,以確保當碰到沒有使用restore處理的運行時緊急情況時,調試會話不會突然結束。

打印變量

程序的執行已在第9行暫停。print是用于打印變量值的命令。讓我們使用print并在切片的第0個索引處打印元素。

(dlv) print arr[0]

運行上面的命令將打印101

請注意,如果嘗試打印max,則會得到一個垃圾值。

(dlv) print max824634294736

這是因為程序在行號9之前已暫停。因此打印會max打印一些隨機的垃圾值。要打印max的實際值,我們應該移至程序的下一行。可以使用next命令來完成。

(dlv) next

調試器將移至下一行,并輸出

> main.main() ./main.go:10 (PC: 0x10c16ee) 5: ) 6: 7: func main() { 8: arr := []int{101, 95, 10, 188, 100} 9: max := arr[0]=> 10: for _, v := range arr { 11: if v > max { 12: max = v 13: } 14: } 15: fmt.Printf("Max element is %d", max)

現在,如果我們嘗試(dlv) print max,可以看到輸出101

next命令可用于逐行瀏覽程序。

如果繼續輸入next,則可以看到調試器在程序中逐行運行。當循環中的第一個for循環重復一次時。第10行結束了, next將引導我們完成下一個迭代,最終程序將終止。

打印表達式

print也可以用于打印表達式。例如,如果我們要查找的值為max + 10,則可以使用print。

讓我們在完成for循環外添加另一個斷點。

(dlv) break main.go:15

上面的命令在行號15上添加了另一個斷點。此時max的計算已完成。

鍵入continue,程序將在此斷點處停止。

print max + 10命令將輸出198。

清除斷點

clear是清除單個斷點的命令,clearall是清除程序中所有斷點的命令。

首先讓我們列出應用程序中的斷點。

(dlv) breakpointsBreakpoint runtime-fatal-throw at 0x102de10 for runtime.fatalthrow() /usr/local/Cellar/go/1.13.7/libexec/src/runtime/panic.go:820 (0) Breakpoint unrecovered-panic at 0x102de80 for runtime.fatalpanic() /usr/local/Cellar/go/1.13.7/libexec/src/runtime/panic.go:847 (0) print runtime.curg._panic.argBreakpoint 1 at 0x10c16e4 for main.main() ./main.go:9 (1) Breakpoint 2 at 0x10c1785 for main.main() ./main.go:15 (1)

我們有兩個斷點分別是1和2

如果我們運行clear 1,它將刪除斷點1。

(dlv) clear 1Breakpoint 1 cleared at 0x10c16e4 for main.main() ./main.go:9

如果運行clearall,它將刪除所有的斷點。現在我們只剩下一個斷點2。

(dlv) clearallBreakpoint 2 cleared at 0x10c1785 for main.main() ./main.go:15

從上面的輸出中,我們可以看到剩余的一個斷點也被清除了。如果我們現在執行continue命令,程序將打印max的值并終止。

(dlv) continueMax element is 188 Process 3095 has exited with status 0

踏入和退出功能

可以使用Delve進入或離開函數。讓我們嘗試借助示例來理解這一點。

package mainimport ( "fmt")func max(arr []int) int { max := arr[0] for _, v := range arr { if v > max { max = v } } return max}func main() { arr := []int{101, 95, 10, 188, 100} m := max(arr) fmt.Printf("Max element is %d", m)}

我已經修改了到目前為止一直在使用的程序,并將查找切片最大元素的邏輯移到了名為max的函數中。

使用退出命令Delve (dlv) q退出調試,把main.go替換為上面的程序,然后使用命令再次開始調試dlv debug。

讓我們在18行上添加一個斷點。

b是添加斷點的簡寫。

(dlv) b main.go:18(dlv) continue

我們在第18行添加了斷點,并繼續執行程序。運行以上命令將打印,

> main.main() ./main.go:18 (hits goroutine(1):1 total:1) (PC: 0x10c17ae) 13: } 14: return max 15: } 16: func main() { 17: arr := []int{101, 95, 10, 188, 100}=> 18: m := max(arr) 19: fmt.Printf("Max element is %d", m) 20: }

程序執行已在第18行暫停。跟我們預期的一樣。現在我們有兩個選擇。

  • 繼續深入調試max函數的功能
  • 跳過max函數,然后移至下一行。

根據我們的要求,我們可以選擇其中一種。

首先,讓我們跳過max函數,移至下一行。為此,您可以運行next,調試器將自動移至下一行。默認情況下,Delve不會更深入地調試函數調用。

(dlv) next> main.main() ./main.go:19 (PC: 0x10c17d3) 14: return max 15: } 16: func main() { 17: arr := []int{101, 95, 10, 188, 100} 18: m := max(arr)=> 19: fmt.Printf("Max element is %d", m) 20: }

您可以從上面的輸出中看到調試器已移至下一行。

鍵入continue,程序將完成執行。

讓我們學習如何更深入地了解max函數。

鍵入restart和continue,我們可以看到程序在已經存在的斷點處再次暫停。

(dlv) restartProcess restarted with PID 5378 (dlv) continue> main.main() ./main.go:18 (hits goroutine(1):1 total:1) (PC: 0x10c17ae) 13: } 14: return max 15: } 16: func main() { 17: arr := []int{101, 95, 10, 188, 100}=> 18: m := max(arr) 19: fmt.Printf("Max element is %d", m) 20: }

現在輸入step,我們可以看到調試器已經移入max函數中了。

(dlv) step> main.max() ./main.go:7 (PC: 0x10c1650) 2: 3: import ( 4: "fmt" 5: ) 6: => 7: func max(arr []int) int { 8: max := arr[0] 9: for _, v := range arr { 10: if v > max { 11: max = v 12: }

鍵入next,控件將移至max函數的第一行。

(dlv) next> main.max() ./main.go:8 (PC: 0x10c1667) 3: import ( 4: "fmt" 5: ) 6: 7: func max(arr []int) int {=> 8: max := arr[0] 9: for _, v := range arr { 10: if v > max { 11: max = v 12: } 13: }

如果繼續輸入next,則可以逐步執行max函數的執行路徑。

您可能想知道是否可以不通過max函數中的每一行而返回到main。使用stepout命令可以做到這一點。

(dlv) stepout> main.main() ./main.go:18 (PC: 0x10c17c9)Values returned: ~r1: 188 13: } 14: return max 15: } 16: func main() { 17: arr := []int{101, 95, 10, 188, 100}=> 18: m := max(arr) 19: fmt.Printf("Max element is %d", m) 20: }

鍵入stepout后,控件將返回到main。現在您可以在main中繼續調試。

打印堆棧跟蹤

調試時需要的一個非常重要的功能是打印程序的當前堆棧跟蹤。這對于查找當前代碼執行路徑很有用。stack是用于打印當前堆棧跟蹤的命令。

讓我們清除所有斷點,在第11行處添加一個新的斷點,并打印程序的當前堆棧跟蹤。

(dlv) restart(dlv) clearall(dlv) b main.go:11(dlv) continue

當程序在斷點處暫停時,鍵入

(dlv) stack

它將輸出程序的當前堆棧跟蹤。

0 0x00000000010c16e8 in main.max at ./main.go:111 0x00000000010c17c9 in main.main at ./main.go:182 0x000000000102f754 in runtime.main at /usr/local/Cellar/go/1.13.7/libexec/src/runtime/proc.go:2033 0x000000000105acc1 in runtime.goexit at /usr/local/Cellar/go/1.13.7/libexec/src/runtime/asm_amd64.s:1357

到目前為止,我們已經介紹了Delve的基本命令,來幫助使用Delve調試應用程序。在接下來的教程中,我們將介紹Delve的高級功能,例如調試goroutine,將調試器附加到現有進程,遠程調試以及使用VSCode編輯器中的Delve。

謝謝閱讀,請留下您的意見和反饋。

總結

以上是生活随笔為你收集整理的是否要运行此应用程序_使用Delve调试Go应用程序的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。