調試Go語言的核心轉儲(Core Dumps)

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

翻譯原文連結 轉帖/轉載請註明出處

英文原文連結【Go, the unwritten parts】 發表於2017/05/22 作者JBD是Go語言開發小組成員

檢查程式的執行路徑和目前狀態是非常有用的調試手段。核心檔案(core file)包含了一個運行進程的記憶體轉儲和狀態。它主要是用來作為事後偵錯工具用的。它也可以被用來查看一個運行中的程式的狀態。這兩個使用情境使調試檔案轉儲成為一個非常好的診斷手段。我們可以用這個方法來做事後診斷和分析線上的服務(production services)。

在這篇文章中,我們將用一個簡單的hello world網站服務作為例子。在現實中,我們的程式很容易就會變得很複雜。分析核心轉儲給我們提供了一個機會去重構程式的狀態並且查看只有在某些條件/環境下才能重現的案例。

作者注: 這個調試流程只在Linux上可行。我不是很確定它是否在其它Unixs系統上工作。macOS對此還不支援。Windows現在也不支援。

在我們開始前,需要確保核心轉儲的ulimit設定在合適的範圍。它的預設值是0,意味著最大的核心檔案大小是0。我通常在我的開發機器上將它設定成unlimited。使用以下命令:

$ ulimit -c unlimited

接下來,你需要在你的機器上安裝delve。

下面我們使用的main.go檔案。它註冊了一個簡單的請求處理函數(handler)然後啟動了HTTP服務。

$ cat main.gopackage mainimport (    "fmt"    "log"    "net/http")func main() {    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {        fmt.Fprint(w, "hello world\n")    })    log.Fatal(http.ListenAndServe("localhost:7777", nil))}

讓我們編譯並生產二進位檔案。

$ go build .

現在讓我們假設,這個伺服器出了些問題,但是我們並不是很確定問題的根源。你可能已經在程式裡加了很多輔助資訊,但還是無法從這些調試資訊中找出線索。通常在這種情況下,當前進程的快照會非常有用。我們可以用這個快照深入查看程式的目前狀態。

有幾個方式來擷取核心檔案。你可能已經熟悉了奔潰轉儲(crash dumps)。它們是在一個程式奔潰的時候寫入磁碟的核心轉儲。Go語言在預設設定下不會生產奔潰轉儲。但是當你把GOTRACEBACK環境變數設定成“crash”,你就可以用Ctrl+backslash才觸發奔潰轉儲。如所示:

$ GOTRACEBACK=crash ./hello(Ctrl+\)

上面的操作會使程式終止,將堆疊追蹤(stack trace)列印出來,並把核心轉儲檔案寫入磁碟。

另外個方法可以從一個啟動並執行程式獲得核心轉儲而不需要終止相應的進程。gcore可以生產核心檔案而無需使運行中的程式退出。

$ ./hello &$ gcore 546 # 546 is the PID of hello.

根據上面的操作,我們獲得了轉儲而沒有終止對應的進程。下一步就是把核心檔案載入進delve並開始分析。

$ dlv core ./hello core.546

差不多就這些。delve的常用操作都可以使用。你可以backtrace,list,查看變數等等。有些功能不可用因為我們使用的核心轉儲是一個快照而不是正在啟動並執行進程。但是程式執行路徑和狀態全部可以訪問。

(dlv) bt 0  0x0000000000457774 in runtime.raise    at /usr/lib/go/src/runtime/sys_linux_amd64.s:110 1  0x000000000043f7fb in runtime.dieFromSignal    at /usr/lib/go/src/runtime/signal_unix.go:323 2  0x000000000043f9a1 in runtime.crash    at /usr/lib/go/src/runtime/signal_unix.go:409 3  0x000000000043e982 in runtime.sighandler    at /usr/lib/go/src/runtime/signal_sighandler.go:129 4  0x000000000043f2d1 in runtime.sigtrampgo    at /usr/lib/go/src/runtime/signal_unix.go:257 5  0x00000000004579d3 in runtime.sigtramp    at /usr/lib/go/src/runtime/sys_linux_amd64.s:262 6  0x00007ff68afec330 in (nil)    at :0 7  0x000000000040f2d6 in runtime.notetsleep    at /usr/lib/go/src/runtime/lock_futex.go:209 8  0x0000000000435be5 in runtime.sysmon    at /usr/lib/go/src/runtime/proc.go:3866 9  0x000000000042ee2e in runtime.mstart1    at /usr/lib/go/src/runtime/proc.go:118210  0x000000000042ed04 in runtime.mstart    at /usr/lib/go/src/runtime/proc.go:1152(dlv) ls> runtime.raise() /usr/lib/go/src/runtime/sys_linux_amd64.s:110 (PC: 0x457774)   105:     SYSCALL   106:     MOVL    AX, DI  // arg 1 tid   107:     MOVL    sig+0(FP), SI   // arg 2   108:     MOVL    $200, AX    // syscall - tkill   109:     SYSCALL=> 110:     RET   111:   112: TEXT runtime·raiseproc(SB),NOSPLIT,$0   113:     MOVL    $39, AX // syscall - getpid   114:     SYSCALL   115:     MOVL    AX, DI  // arg 1 pid

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.