go 运行时:gccheckmark 什么也不做?

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

你正在使用的Go版本是什么( go version )?

  1. $ go version
  2. go version go1.23.0 darwin/amd64

这个问题在最新版本中是否会重现?

你正在使用什么操作系统和处理器架构( go env )?

go env 输出

  1. $ go env
  2. GO111MODULE=''
  3. GOARCH='amd64'
  4. GOBIN=''
  5. GOCACHE='/Users/mm/Library/Caches/go-build'
  6. GOENV='/Users/mm/Library/Application Support/go/env'
  7. GOEXE=''
  8. GOEXPERIMENT=''
  9. GOFLAGS=''
  10. GOHOSTARCH='amd64'
  11. GOHOSTOS='darwin'
  12. GOINSECURE=''
  13. GOMODCACHE='/Users/mm/go/pkg/mod'
  14. GONOPROXY=''
  15. GONOSUMDB=''
  16. GOOS='darwin'
  17. GOPATH='/Users/mm/go'
  18. GOPRIVATE=''
  19. GOPROXY='https://proxy.golang.org,direct'
  20. GOROOT='/usr/local/go'
  21. GOSUMDB='sum.golang.org'
  22. GOTMPDIR=''
  23. GOTOOLCHAIN='auto'
  24. GOTOOLDIR='/usr/local/go/pkg/tool/darwin_amd64'
  25. GOVCS=''
  26. GOVERSION='go1.23.0'
  27. GODEBUG=''
  28. GOTELEMETRY='local'
  29. GOTELEMETRYDIR='/Users/mm/Library/Application Support/go/telemetry'
  30. GCCGO='gccgo'
  31. GOAMD64='v1'
  32. AR='ar'
  33. CC='/usr/bin/clang'
  34. CXX='clang++'
  35. CGO_ENABLED='1'
  36. GOMOD='/Users/mm/go/src/github.com/MikeMitchellWebDev/gc_knobs/go.mod'
  37. GOWORK=''
  38. CGO_CFLAGS='-O2 -g'
  39. CGO_CPPFLAGS=''
  40. CGO_CXXFLAGS='-O2 -g'
  41. CGO_FFLAGS='-O2 -g'
  42. CGO_LDFLAGS='-O2 -g'
  43. PKG_CONFIG='pkg-config'
  44. GOGCCFLAGS='-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/5y/wtzzmjlj5v52pg7wr8ptbg_m0000gp/T/go-build534087183=/tmp/go-build -gno-record-gcc-switches -fno-common'
  45. uname -v: Darwin Kernel Version 20.6.0: Thu Jul 6 22:12:47 PDT 2023; root:xnu-7195.141.49.702.12~1/RELEASE_X86_64
  46. ProductName: macOS
  47. ProductVersion: 11.7.10
  48. BuildVersion: 20G1427
  49. lldb --version: lldb-1300.0.42.3
  50. Swift version 5.5.2-dev

你做了什么?

我做了两件事:首先,我用 GODEBUG=gccheckmark=1. 运行了一个程序。当 setCheckmark 没有被调用时,我尝试在手动设置 var useCheckmark = true 后构建go源代码。

你期望看到什么?

这取决于我是否只是用 GODEBUG=gccheckmark=1 运行了一个程序,或者像上面描述的那样修改了源代码。

  1. setCheckmark在某个时刻被调用
  2. 在设置 useCheckmark = true 后构建的源代码

你看到了什么?

  1. 在使用 "as is" 的源代码的情况下,setCheckmark从未被调用。在 gcMarkTermination 内部,useCheckmark被设置为true的时间非常短,所以mgcmark.go中的这行代码永远不会运行
  1. if useCheckmark {
  2. if setCheckmark(obj, base, off, mbits) {
  1. 当我手动将 useCheckmark = true 时,源代码无法构建。总是会出现致命错误 "fatal error: checkmark found unmarked object"
2izufjch

2izufjch2#

cc @golang/runtime @aclements@mknyszek

guykilcj

guykilcj3#

当我手动设置useCheckmark = true时,源代码无法构建。总是会出现致命错误 "fatal error: checkmark found unmarked object"。我认为这部分并不令人惊讶。请注意,useCheckmark通常仅在每次GC期间临时启用:https://cs.opensource.google/go/go/+/master:src/runtime/mgc.go;l=999-1005;drc=96d8ff00c2d6a88384863a656fb5e53716b614d3;bpv=1;bpt=1

2ledvvac

2ledvvac4#

+1 赞同 @prattmic 的观点,直接设置 useCheckmark 不会达到预期效果。这是因为在 checkmark 模式下存在一些内部状态。
关于:
当 setCheckmark 没有被调用时
你是如何检查 setCheckmark 是否被调用的?
setCheckmark 被设置为 true 的时间窗口非常狭窄
我认为你误解了这段代码的作用。这不是一个狭窄的窗口,实际上它在世界停止运行的同时,有效地运行了一整个单线程的垃圾回收周期。

vxqlmq5t

vxqlmq5t5#

感谢您的反馈,确实存在一个问题。我发现 gcResetMarkState 无法重置根标记作业计数器,因此没有扫描根节点,因此 setCheckmark 永远不会被调用。我认为这个问题很容易解决;我会尝试一下。
此外,这段代码确实应该至少有一个简单的测试...

noj0wjuj

noj0wjuj6#

https://go.dev/cl/608915提到了这个问题:runtime: fix GODEBUG=gccheckmark=1 and add smoke test

相关问题