如何在Golang中获取线程转储?

如何在Golang中获取线程转储? 我需要在Windows环境下获取线程转储。

6 回复

你所说的"线程转储"具体是指什么?

更多关于如何在Golang中获取线程转储?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我的意思是,如何查看正在运行的 goroutine。

就像在 Java 中我们可以通过线程转储来检查线程状态。

使用 jstack。

有没有在 Windows 和 Linux 上查看 goroutine 状态的替代方法。

可以使用一个标志:

GODEBUG=schedtrace=1000 ./yourProgram

更详细的模式:

GODEBUG=scheddetail=1,schedtrace=100 ./yourProgram

也许这会有帮助
https://golang.org/pkg/runtime/debug/


线程转储是构成进程的所有线程状态的快照。每个线程的状态通过所谓的堆栈跟踪呈现,其中显示了线程堆栈的内容。

如下所示:

package main

import (
  "os"
  "runtime/pprof"
)

func main() {
  pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
}

输出结果:

$ go run main.go
goroutine profile: total 1
1 @ 0x10ad368 0x10ad170 0x10a9bd4 0x10b3ee5 0x102a407 0x1052dc1
#       0x10ad367       runtime/pprof.writeRuntimeProfile+0x97  /usr/local/go/src/runtime/pprof/pprof.go:707
#       0x10ad16f       runtime/pprof.writeGoroutine+0x9f       /usr/local/go/src/runtime/pprof/pprof.go:669
#       0x10a9bd3       runtime/pprof.(*Profile).WriteTo+0x3e3  /usr/local/go/src/runtime/pprof/pprof.go:328
#       0x10b3ee4       main.main+0x64                          /Users/inanc/go/src/github.com/inancgumus/main.go:9
#       0x102a406       runtime.main+0x206                      /usr/local/go/src/runtime/proc.go:201

在Windows环境下,Go语言中获取线程转储(thread dump)通常依赖于操作系统工具或调试器,因为Go本身不直接提供跨平台的线程转储API。以下是几种方法:

  1. 使用任务管理器生成转储文件

    • 打开任务管理器(Ctrl+Shift+Esc)。
    • 找到你的Go程序进程,右键点击并选择“创建转储文件”。
    • 这会生成一个.dmp文件,你可以用调试工具(如WinDbg)分析线程状态。
  2. 使用命令行工具ProcDump(来自Sysinternals)

    • 下载并安装ProcDump(微软官网)。
    • 运行命令生成转储文件,例如:
      procdump -ma <PID>
      
      其中<PID>是你的Go程序进程ID。这会创建一个包含线程信息的完整转储文件。
  3. 在Go代码中集成调试支持

    • 使用runtime/pprof包来生成性能分析文件,包括goroutine堆栈,但这主要针对goroutine而非原生线程。例如:
      package main
      
      import (
          "os"
          "runtime/pprof"
      )
      
      func main() {
          f, err := os.Create("goroutine.pprof")
          if err != nil {
              panic(err)
          }
          defer f.Close()
          pprof.Lookup("goroutine").WriteTo(f, 1)
          // 你的程序逻辑
      }
      
      这会在程序运行时生成goroutine堆栈信息,但注意Go的goroutine是用户级线程,与操作系统线程不同。
  4. 使用调试器附加到进程

    • 用WinDbg或Visual Studio附加到Go程序进程,然后使用命令(如~*k)获取所有线程的堆栈。

在Windows上,线程转储通常指原生OS线程,而Go程序使用goroutine调度,因此直接获取OS线程转储可能不如分析goroutine堆栈有用。如果目标是调试goroutine,建议使用pprof

回到顶部