【问题标题】:Generate panic stacktrace on working process在工作进程上生成恐慌堆栈跟踪
【发布时间】:2019-08-10 19:33:31
【问题描述】:

情况:

我的 Go 服务器程序存在竞争条件问题:

go func() {
    i := 1
    for {
        fmt.Printf("I am alive: %d\n",i)
        time.Sleep(1 * time.Second)
        i+=1
    }
}()

在对我的程序进行大量并行请求后,它完全挂掉了,甚至 main 中的 goroutine 也没有再写任何东西。

问题:

我想消除这个问题。为此,我想在这种状态下生成一个 panic 并接收所有 goroutine 的堆栈转储。

有什么办法吗?

【问题讨论】:

  • 使用-race 选项(例如go run -race xx.go)运行您的应用程序,如果在运行时检测到数据竞争,它将提醒您(将源文件名和确切的行打印到控制台)。
  • 在这种情况下它没有多大帮助 - 我没有可以通过 -race 检测到的竞态条件。这就是为什么我首先要查找程序的当前状态。
  • 你向 go 程序发送 SIGQUIT 以使其转储堆栈跟踪
  • 哦,如果一切最终都冻结了,那通常是某处繁忙循环的迹象。
  • @JimB: SIGQUIT 这确实是我一直在寻找的——它可以被接受为我的问题的答案。

标签: go


【解决方案1】:

如果您想从 Go 进程中获取堆栈跟踪,SIGQUIT 的默认信号处理程序将打印堆栈跟踪并退出。

还有一些有用的设置可以通过GODEBUGGOTRACEBACK 环境变量启用,记录在runtime package 中。在这种情况下,使用schedtracescheddetailgctrace 可能有助于显示程序冻结时发生的情况。

【讨论】:

    【解决方案2】:

    种族检测

    您说您有比赛,您应该尝试使用-race 选项运行您的应用程序,例如

    go run -race xx.go
    

    如果在运行时检测到数据竞争,它将提醒您(将源文件名和确切的行打印到控制台)。

    分析

    如果这没有帮助(未检测到竞态,因为它们可能不会发生),那么您应该分析您的应用。有一个标准的HTTP接口来分析数据,参见net/http/pprof的包文档。

    基本上import _ "net/http/pprof",然后启动您的应用并访问(使用您的端口):

    http://localhost:8080/debug/pprof/
    

    如果您的应用尚未启动 Web 服务器,那么您必须这样做:将 net/httplog 添加到您的导入中,并将以下代码添加到您的 main 函数中:

    go func() {
        log.Println(http.ListenAndServe("localhost:8080", nil))
    }()
    

    可以在以下位置查看堆栈跟踪

    http://localhost:8080/debug/pprof/goroutine?debug=1
    

    和完整的堆栈跟踪

    http://localhost:8080/debug/pprof/goroutine?debug=2
    

    这些页面允许您查看实时应用程序的所有 goroutine 的完整堆栈跟踪,而无需终止它。

    其他有用的资源

    The Go Blog: Profiling Go Programs

    The Go Blog: Introducing the Go Race Detector

    Debugging Go Code with GDB

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-25
      • 2023-03-05
      • 1970-01-01
      • 1970-01-01
      • 2012-11-08
      • 2015-01-03
      • 1970-01-01
      相关资源
      最近更新 更多