假设我有一堆 goroutine 的堆栈跟踪,例如:
goroutine 5633 [select]:
net/http.(*persistConn).writeLoop(0xc21303ac00)
/usr/lib/go/src/pkg/net/http/transport.go:791 +0x271
created by net/http.(*Transport).dialConn
/usr/lib/go/src/pkg/net/http/transport.go:529 +0x61e
Run Code Online (Sandbox Code Playgroud)
在我的例子中,一个独特的特定于应用程序的对象由一组 goroutine 提供服务,我想查看与特定对象相关的 goroutine 的堆栈跟踪。我有数百个特定于应用程序的对象,所以我得到了数百个相同的 goroutine。
我将如何将我的日志与堆栈跟踪中的 goroutine 相关联?似乎没有一种方法可以在堆栈跟踪中识别当前 goroutine,也无法命名 goroutine,因此我可以在堆栈跟踪中看到特定值。
聚苯乙烯
我已经在 Go 邮件列表上阅读了相关的为什么你想要做的帖子,所以我正在寻找替代方案/黑客/解决方法(希望不涉及用日志散布代码每隔一行调用一次)。
小智 6
这个方法比 @Alex B 更简单。它使用 debug.Stack() 以字节切片形式返回堆栈跟踪的事实,其中包含 goroutine 它在第二个字边界中的 id 以及堆栈跟踪。并解析它。
package main
import (
"bytes"
"fmt"
"runtime/debug"
"sync"
)
func main() {
w := sync.WaitGroup{}
w.Add(1)
go func() {
gr := bytes.Fields(debug.Stack())[1]
fmt.Println(string(gr))
w.Done()
}()
w.Wait()
}
Run Code Online (Sandbox Code Playgroud)
一种解决方法是可能的,并且涉及一小段 C 代码。
#include <runtime.h>
void ·GetGoID(int32 ret) {
ret = g->goid;
USED(&ret);
}
Run Code Online (Sandbox Code Playgroud)
package main
import (
"fmt"
"sync"
)
// Declaration is required
func GetGoID() int32
func main() {
var wg sync.WaitGroup
f := func() {
wg.Add(1)
go func() {
fmt.Printf("goroutine %d\n", GetGoID())
wg.Done()
}()
}
for i := 0; i < 10; i++ {
f()
}
wg.Wait()
}
Run Code Online (Sandbox Code Playgroud)
$ go build
$ ./example
goroutine 20
goroutine 21
goroutine 22
goroutine 23
goroutine 24
goroutine 25
goroutine 26
goroutine 27
goroutine 28
goroutine 29
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3599 次 |
| 最近记录: |