go 运行时/ pprof:没有API可以访问带有MemProfileRecord和BlockProfileRecord的深度堆栈跟踪,

fnatzsnv  于 6个月前  发布在  Go
关注(0)|答案(9)|浏览(199)

Go版本
go版本 devel go1.23-b788e91bad Tue Jun 11 18:08:44 2024 +0000 linux/amd64

在你的模块/工作区中go env的输出:

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/korniltsev/.cache/go-build'
GOENV='/home/korniltsev/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/korniltsev/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/korniltsev/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/korniltsev/github/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/korniltsev/github/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='devel go1.23-b788e91bad Tue Jun 11 18:08:44 2024 +0000'
GODEBUG=''
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/korniltsev/.config/go/telemetry'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/home/korniltsev/github/go/src/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1768278824=/tmp/go-build -gno-record-gcc-switches'

你做了什么?

我比较了runtime.MemProfileruntime/pprof.WriteHeapProfile的堆栈
https://go.dev/play/p/7iUI7DdMI3r?v=gotip

你看到了什么?

我看到MemprofileRecord的堆栈被截断到32深度,而pprof堆栈有正确的深度堆栈。

你期望看到什么?

我期望MemprofileRecord.Stack()返回一个具有正确深度堆栈的切片。

i5desfxk

i5desfxk2#

runtime.MemProfileMemprofileRecord 用于 [godeltaprof] ( https://github.com/grafana/pyroscope-go/tree/main/godeltaprof )
通过链接到 runtime/pprof.memProfileInternal,绕过这些限制可能是可能的,但鉴于 #67401 ,这现在看起来像一个不太吸引人的想法。

6psbrbz9

6psbrbz93#

我为添加深度堆栈跟踪而努力修补了这个问题。顺便说一下,我最初试图通过公共API提供深度堆栈跟踪,参见 v35 of my CL

问题在于实现这个功能会面临各种 go1compat 挑战,所以我们需要一个提案,要么在不引起兼容性问题的情况下解决这个问题,要么就为接受少量兼容性问题达成共识。具体来说:

  1. 我们是否同意打破那些不期望 Stack() 返回超过 Stack0 帧的应用程序?
  2. 如果 StackRecord 类型不再正确比较,我们是否同意?(无论是在规范意义上,还是通过包含一个使比较毫无意义的指针)
  3. 我们是否同意在所有情况下更改 Stack() 返回的切片是否由 Stack0 数组支持的语义?
tct7dpnv

tct7dpnv4#

One of the possible solutions (for godeltaprof) could be to have the same functionality in golang standard library and to deprecate the godeltaprof project alltogether.
#57765
#67942

brvekthn

brvekthn5#

我们与Google的内部峰值堆栈分析实现存在类似的问题。如其名称所示,峰值堆栈分析跟踪高水位堆栈分析。我曾考虑向运行时添加峰值堆栈分析的提案,但我没有足够的时间去深入思考。鉴于我不是唯一遇到这个问题的人,我现在更倾向于通过运行时API导出更大的堆栈。
关于go1compat挑战:我们是否需要更改现有的API,还是可以有一个v2 API(例如在一个新的包中,如runtime/profile)?

a0x5cqrl

a0x5cqrl7#

我相信这是#43669的重复。

eaf3rand

eaf3rand8#

我认为有一些重叠,但这实际上是关于 #43669 的一个特定未解决的部分。同时, #43669 现在基本上已经解决了,因为从 https://go.dev/cl/572396 开始,除了本问题中提到的运行时API之外,深度堆栈在任何地方都可以使用。我认为我们可能应该关闭 #43669 以支持这个问题?

wgeznvg7

wgeznvg79#

当然,如果你认为 #43669 已经完成,那么请随意关闭它。
就个人而言,我认为访问深度堆栈跟踪的 API 是 runtime/pprof,我们只是废弃了旧的 MemProfileRecord 和 BlockProfileRecord 结构体。

相关问题