delve是go官方推荐的一个调试器,由go语言开发,也被很多代码编辑器集成为debug的插件,比如goland,vscode
官方文档戳这里
程序例子
delve安装
调试go运行时程序
- 启动程序
go run test.go
或go build -o test test.go
- 调试程序
- 连接运行时程序
dlv attach `ps aux|grep test|grep -v "grep"|awk '{print $2}'`
- 查看当前进程所有线程信息(即MPG中的M)
(dlv) threads * Thread 130 at 0x45f0a3 .usr/local/go/src/runtime/sys_linux_amd64.s:536 runtime.futex ...... Thread 136 at 0x45f250 .usr/local/go/src/runtime/sys_linux_amd64.s:675 runtime.epollwait
- 切换线程
(dlv) thread 135 Switched from 130 to 135
- 查看当前线程栈详细信息
(dlv) stack 0 0x000000000045f0a3 in runtime.futex at .usr/local/go/src/runtime/sys_linux_amd64.s:536 ...... 7 0x0000000000401893 in ??? at ?:-1
- 查看当前线程运行栈中的某一个函数信息
(dlv) frame 1 > runtime.futex() .usr/local/go/src/runtime/sys_linux_amd64.s:536 (PC: 0x45f0a3) Warning: debugging optimized function Frame 1: .usr/local/go/src/runtime/os_linux.go:63 (PC: 42c4b2) 58: ts.set_nsec(int32(ns % 1000000000)) 59: } else { 60: ts.tv_nsec = 0 61: ts.set_sec(int64(timediv(ns, 1000000000, (*int32)(unsafe.Pointer(&ts.tv_nsec))))) 62: } => 63: futex(unsafe.Pointer(addr), _FUTEX_WAIT_PRIVATE, val, unsafe.Pointer(&ts), nil, 0) 64: } 65: 66: // If any procs are sleeping on addr, wake up at most cnt. 67: //go:nosplit 68: func futexwakeup(addr *uint32, cnt uint32) {
- 查看所有的协程
(dlv) goroutines #或者grs Goroutine 1 - User: .root/go/src/github.com/saileifeng/go-socket-test/example/test/test.go:41 main.ShutDownHook (0x735829) Goroutine 2 - User: .usr/local/go/src/runtime/proc.go:302 runtime.gopark (0x43036f) Goroutine 3 - User: .usr/local/go/src/runtime/proc.go:302 runtime.gopark (0x43036f) Goroutine 4 - User: .usr/local/go/src/runtime/proc.go:302 runtime.gopark (0x43036f) Goroutine 6 - User: .usr/local/go/src/runtime/proc.go:302 runtime.gopark (0x43036f) Goroutine 18 - User: .usr/local/go/src/runtime/sigqueue.go:139 os/signal.signal_recv (0x44450c) Goroutine 19 - User: .usr/local/go/src/runtime/netpoll.go:182 internal/poll.runtime_pollWait (0x42b0a6) Goroutine 20 - User: .usr/local/go/src/runtime/sema.go:71 sync.runtime_SemacquireMutex (0x4402ad) Goroutine 21 - User: .usr/local/go/src/runtime/sema.go:71 sync.runtime_SemacquireMutex (0x4402ad) Goroutine 22 - User: .usr/local/go/src/runtime/sema.go:71 sync.runtime_SemacquireMutex (0x4402ad) Goroutine 23 - User: .usr/local/go/src/runtime/sema.go:71 sync.runtime_SemacquireMutex (0x4402ad) Goroutine 24 - User: .usr/local/go/src/runtime/sema.go:71 sync.runtime_SemacquireMutex (0x4402ad) Goroutine 25 - User: .usr/local/go/src/runtime/sema.go:71 sync.runtime_SemacquireMutex (0x4402ad) Goroutine 26 - User: .usr/local/go/src/runtime/sema.go:71 sync.runtime_SemacquireMutex (0x4402ad) Goroutine 27 - User: .usr/local/go/src/runtime/sema.go:71 sync.runtime_SemacquireMutex (0x4402ad) Goroutine 28 - User: .usr/local/go/src/runtime/sema.go:71 sync.runtime_SemacquireMutex (0x4402ad) Goroutine 29 - User: .usr/local/go/src/runtime/sema.go:71 sync.runtime_SemacquireMutex (0x4402ad) Goroutine 30 - User: .usr/local/go/src/runtime/proc.go:302 runtime.gopark (0x43036f) Goroutine 31 - User: .usr/local/go/src/runtime/proc.go:302 runtime.gopark (0x43036f) [19 goroutines]
- 切换协程
(dlv) goroutine 1 #或者gr 1 Switched from 0 to 1 (thread 131) #可以看到当前协程是在131线程上被运行
- 查看协程栈信息
(dlv) goroutine 1 stack #或者直接stack 0 0x000000000043036f in runtime.gopark at .usr/local/go/src/runtime/proc.go:302 1 0x00000000004075a0 in runtime.goparkunlock at .usr/local/go/src/runtime/proc.go:307 2 0x00000000004075a0 in runtime.chanrecv at .usr/local/go/src/runtime/chan.go:524 3 0x000000000040727b in runtime.chanrecv1 at .usr/local/go/src/runtime/chan.go:406 4 0x0000000000735829 in main.ShutDownHook at .root/go/src/github.com/saileifeng/go-socket-test/example/test/test.go:41 5 0x0000000000735747 in main.main at .root/go/src/github.com/saileifeng/go-socket-test/example/test/test.go:34 6 0x000000000042ff7c in runtime.main at .usr/local/go/src/runtime/proc.go:200 7 0x000000000045d241 in runtime.goexit at .usr/local/go/src/runtime/asm_amd64.s:1337
- 查看协程栈中运行的函数详细信息
(dlv) gr 1 frame 4
- 连接运行时程序
网友评论