goroutine堆栈跟踪不完整

时间:2017-04-19 07:16:02

标签: performance go

我使用golang编写了一个Web应用程序。当它在生产中运行时,有一些goroutine被阻止。以下是信息(使用pprof生成):

goroutine 792247 [chan receive, 948 minutes]:
database/sql.(*Tx).awaitDone(0xc4206e2b80)
    /usr/local/go/src/database/sql/sql.go:1440 +0x57
created by database/sql.(*DB).begin
    /usr/local/go/src/database/sql/sql.go:1383 +0x274

goroutine一直在等待948分钟的频道。显然,有些不对劲。但堆栈跟踪似乎不完整。我发现这个bug是不够的。 (我希望从我的程序开始一些堆栈跟踪。)

如何获得此goroutine的完整堆栈跟踪? 或者还有其他方法可以调试此问题吗?

更新

我已经阅读了database / sql / sql.go的源代码。事实证明database/sql/sql.go:1440是一个新的goroutine。堆栈跟踪为incomplete,因为先前的堆栈跟踪属于parent goroutine。

我的问题应该是:有没有更好的方法来调试这个问题?

1 个答案:

答案 0 :(得分:0)

我认为没有任何方法可以获取父goroutine堆栈,而无需手动跟踪每个go例程调用并为其生成id。

在这种特定情况下,您可能会有一个未提交或回滚的事务,因为发生错误并且函数过早退出而没有调用。

避免相同的一个好模板是使用'延迟'。

func (s Service) DoSomething() (err error) {
    tx, err := s.db.Begin()
    if err != nil {
        return
    }
    defer func() {
        if err != nil {
            tx.Rollback()
            return
        }
        err = tx.Commit()
    }()
    if _, err = tx.Exec(...); err != nil {
        return
    }
    if _, err = tx.Exec(...); err != nil {
        return
    }
    // ...
    return }

Code Reference

PS:小心错误阴影。