[go/release-branch.go1.25] [release-branch.go1.25] runtime: initialise debug settings much earlier in startup process

1 view
Skip to first unread message

Carlos Amedee (Gerrit)

unread,
11:42 AM (11 hours ago) 11:42 AM
to goph...@pubsubhelper.golang.org, Steve Muir, golang-co...@googlegroups.com

Carlos Amedee has uploaded the change for review

Commit message

[release-branch.go1.25] runtime: initialise debug settings much earlier in startup process

This is necessary specifically to set the value of `debug.decoratemappings`
sufficiently early in the startup sequence that all memory ranges allocated
can be named appropriately using the new Linux-specific naming API
introduced in #71546.

Example output (on ARM64):
https://gist.github.com/9muir/3667654b9c3f52e8be92756219371672

For: #75324
Fixes #75669

Change-Id: Ic0b16233f54a45adef1660c4d0df59af2f5af86a
Reviewed-on: https://go-review.googlesource.com/c/go/+/703476
Auto-Submit: Michael Knyszek <mkny...@google.com>
LUCI-TryBot-Result: Go LUCI <golang...@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Knyszek <mkny...@google.com>
(cherry picked from commit 300d9d2714164e455abc7990d52de9de6b084df1)

Change diff

diff --git a/src/runtime/decoratemappings_test.go b/src/runtime/decoratemappings_test.go
new file mode 100644
index 0000000..7d1121c
--- /dev/null
+++ b/src/runtime/decoratemappings_test.go
@@ -0,0 +1,72 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import (
+ "os"
+ "regexp"
+ "runtime"
+ "testing"
+)
+
+func validateMapLabels(t *testing.T, labels []string) {
+ // These are the specific region labels that need get added during the
+ // runtime phase. Hence they are the ones that need to be confirmed as
+ // present at the time the test reads its own region labels, which
+ // is sufficient to validate that the default `decoratemappings` value
+ // (enabled) was set early enough in the init process.
+ regions := map[string]bool{
+ "allspans array": false,
+ "gc bits": false,
+ "heap": false,
+ "heap index": false,
+ "heap reservation": false,
+ "immortal metadata": false,
+ "page alloc": false,
+ "page alloc index": false,
+ "page summary": false,
+ "scavenge index": false,
+ }
+ for _, label := range labels {
+ if _, ok := regions[label]; !ok {
+ t.Logf("unexpected region label found: \"%s\"", label)
+ }
+ regions[label] = true
+ }
+ for label, found := range regions {
+ if !found {
+ t.Logf("region label missing: \"%s\"", label)
+ }
+ }
+}
+
+func TestDecorateMappings(t *testing.T) {
+ if runtime.GOOS != "linux" {
+ t.Skip("decoratemappings is only supported on Linux")
+ // /proc/self/maps is also Linux-specific
+ }
+
+ var labels []string
+ if rawMaps, err := os.ReadFile("/proc/self/maps"); err != nil {
+ t.Fatalf("failed to read /proc/self/maps: %v", err)
+ } else {
+ t.Logf("maps:%s\n", string(rawMaps))
+ matches := regexp.MustCompile("[^[]+ \\[anon: Go: (.+)\\]\n").FindAllSubmatch(rawMaps, -1)
+ for _, match_pair := range matches {
+ // match_pair consists of the matching substring and the parenthesized group
+ labels = append(labels, string(match_pair[1]))
+ }
+ }
+ t.Logf("DebugDecorateMappings: %v", *runtime.DebugDecorateMappings)
+ if *runtime.DebugDecorateMappings != 0 && runtime.SetVMANameSupported() {
+ validateMapLabels(t, labels)
+ } else {
+ if len(labels) > 0 {
+ t.Errorf("unexpected mapping labels present: %v", labels)
+ } else {
+ t.Skip("mapping labels absent as expected")
+ }
+ }
+}
diff --git a/src/runtime/export_test.go b/src/runtime/export_test.go
index 9a4611e..6559ece 100644
--- a/src/runtime/export_test.go
+++ b/src/runtime/export_test.go
@@ -1927,3 +1927,7 @@
func TraceStack(gp *G, tab *TraceStackTable) {
traceStack(0, gp, (*traceStackTable)(tab))
}
+
+var DebugDecorateMappings = &debug.decoratemappings
+
+func SetVMANameSupported() bool { return setVMANameSupported() }
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index b41bbe9..d898c96 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -789,7 +789,9 @@
// getGodebugEarly extracts the environment variable GODEBUG from the environment on
// Unix-like operating systems and returns it. This function exists to extract GODEBUG
// early before much of the runtime is initialized.
-func getGodebugEarly() string {
+//
+// Returns nil, false if OS doesn't provide env vars early in the init sequence.
+func getGodebugEarly() (string, bool) {
const prefix = "GODEBUG="
var env string
switch GOOS {
@@ -807,12 +809,16 @@
s := unsafe.String(p, findnull(p))

if stringslite.HasPrefix(s, prefix) {
- env = gostring(p)[len(prefix):]
+ env = gostringnocopy(p)[len(prefix):]
break
}
}
+ break
+
+ default:
+ return "", false
}
- return env
+ return env, true
}

// The bootstrap sequence is:
@@ -859,11 +865,14 @@
// The world starts stopped.
worldStopped()

+ godebug, parsedGodebug := getGodebugEarly()
+ if parsedGodebug {
+ parseRuntimeDebugVars(godebug)
+ }
ticks.init() // run as early as possible
moduledataverify()
stackinit()
mallocinit()
- godebug := getGodebugEarly()
cpuinit(godebug) // must run before alginit
randinit() // must run before alginit, mcommoninit
alginit() // maps, hash, rand must not be used before this call
@@ -880,7 +889,12 @@
goenvs()
secure()
checkfds()
- parsedebugvars()
+ if !parsedGodebug {
+ // Some platforms, e.g., Windows, didn't make env vars available "early",
+ // so try again now.
+ parseRuntimeDebugVars(gogetenv("GODEBUG"))
+ }
+ finishDebugVarsSetup()
gcinit()

// Allocate stack space that can be used when crashing due to bad stack
diff --git a/src/runtime/runtime1.go b/src/runtime/runtime1.go
index 424745d..15b5467 100644
--- a/src/runtime/runtime1.go
+++ b/src/runtime/runtime1.go
@@ -402,7 +402,7 @@
{name: "updatemaxprocs", value: &debug.updatemaxprocs, def: 1},
}

-func parsedebugvars() {
+func parseRuntimeDebugVars(godebug string) {
// defaults
debug.cgocheck = 1
debug.invalidptr = 1
@@ -420,12 +420,6 @@
}
debug.traceadvanceperiod = defaultTraceAdvancePeriod

- godebug := gogetenv("GODEBUG")
-
- p := new(string)
- *p = godebug
- godebugEnv.Store(p)
-
// apply runtime defaults, if any
for _, v := range dbgvars {
if v.def != 0 {
@@ -437,7 +431,6 @@
}
}
}
-
// apply compile-time GODEBUG settings
parsegodebug(godebugDefault, nil)

@@ -463,6 +456,12 @@
if debug.gccheckmark > 0 {
debug.asyncpreemptoff = 1
}
+}
+
+func finishDebugVarsSetup() {
+ p := new(string)
+ *p = gogetenv("GODEBUG")
+ godebugEnv.Store(p)

setTraceback(gogetenv("GOTRACEBACK"))
traceback_env = traceback_cache
diff --git a/src/runtime/set_vma_name_linux.go b/src/runtime/set_vma_name_linux.go
index 100c2bf..792d6ad 100644
--- a/src/runtime/set_vma_name_linux.go
+++ b/src/runtime/set_vma_name_linux.go
@@ -14,9 +14,13 @@

var prSetVMAUnsupported atomic.Bool

+func setVMANameSupported() bool {
+ return !prSetVMAUnsupported.Load()
+}
+
// setVMAName calls prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, start, len, name)
func setVMAName(start unsafe.Pointer, length uintptr, name string) {
- if debug.decoratemappings == 0 || prSetVMAUnsupported.Load() {
+ if debug.decoratemappings == 0 || !setVMANameSupported() {
return
}

diff --git a/src/runtime/set_vma_name_stub.go b/src/runtime/set_vma_name_stub.go
index 38f65fd..6cb01eb 100644
--- a/src/runtime/set_vma_name_stub.go
+++ b/src/runtime/set_vma_name_stub.go
@@ -10,3 +10,5 @@

// setVMAName isn’t implemented
func setVMAName(start unsafe.Pointer, len uintptr, name string) {}
+
+func setVMANameSupported() bool { return false }

Change information

Files:
  • A src/runtime/decoratemappings_test.go
  • M src/runtime/export_test.go
  • M src/runtime/proc.go
  • M src/runtime/runtime1.go
  • M src/runtime/set_vma_name_linux.go
  • M src/runtime/set_vma_name_stub.go
Change size: M
Delta: 6 files changed, 109 insertions(+), 14 deletions(-)
Open in Gerrit

Related details

Attention set is empty
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: newchange
Gerrit-Project: go
Gerrit-Branch: release-branch.go1.25
Gerrit-Change-Id: Ic0b16233f54a45adef1660c4d0df59af2f5af86a
Gerrit-Change-Number: 708359
Gerrit-PatchSet: 1
Gerrit-Owner: Carlos Amedee <car...@golang.org>
Gerrit-CC: Steve Muir <sjm...@google.com>
unsatisfied_requirement
satisfied_requirement
open
diffy

Carlos Amedee (Gerrit)

unread,
11:43 AM (11 hours ago) 11:43 AM
to Steve Muir, goph...@pubsubhelper.golang.org, Michael Knyszek, Cherry Mui, golang-co...@googlegroups.com
Attention needed from Cherry Mui and Michael Knyszek

Carlos Amedee voted Commit-Queue+1

Commit-Queue+1
Open in Gerrit

Related details

Attention is currently required from:
  • Cherry Mui
  • Michael Knyszek
Submit Requirements:
  • requirement is not satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: go
Gerrit-Branch: release-branch.go1.25
Gerrit-Change-Id: Ic0b16233f54a45adef1660c4d0df59af2f5af86a
Gerrit-Change-Number: 708359
Gerrit-PatchSet: 1
Gerrit-Owner: Carlos Amedee <car...@golang.org>
Gerrit-Reviewer: Carlos Amedee <car...@golang.org>
Gerrit-Reviewer: Cherry Mui <cher...@google.com>
Gerrit-Reviewer: Michael Knyszek <mkny...@google.com>
Gerrit-CC: Steve Muir <sjm...@google.com>
Gerrit-Attention: Cherry Mui <cher...@google.com>
Gerrit-Attention: Michael Knyszek <mkny...@google.com>
Gerrit-Comment-Date: Wed, 01 Oct 2025 15:43:34 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
unsatisfied_requirement
satisfied_requirement
open
diffy

Cherry Mui (Gerrit)

unread,
11:47 AM (11 hours ago) 11:47 AM
to Steve Muir, Carlos Amedee, goph...@pubsubhelper.golang.org, Go LUCI, Michael Knyszek, golang-co...@googlegroups.com
Attention needed from Carlos Amedee and Michael Knyszek

Cherry Mui voted Code-Review+2

Code-Review+2
Open in Gerrit

Related details

Attention is currently required from:
  • Carlos Amedee
  • Michael Knyszek
Submit Requirements:
  • requirement satisfiedCode-Review
  • requirement satisfiedNo-Unresolved-Comments
  • requirement satisfiedReview-Enforcement
  • requirement is not satisfiedTryBots-Pass
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: go
Gerrit-Branch: release-branch.go1.25
Gerrit-Change-Id: Ic0b16233f54a45adef1660c4d0df59af2f5af86a
Gerrit-Change-Number: 708359
Gerrit-PatchSet: 1
Gerrit-Owner: Carlos Amedee <car...@golang.org>
Gerrit-Reviewer: Carlos Amedee <car...@golang.org>
Gerrit-Reviewer: Cherry Mui <cher...@google.com>
Gerrit-Reviewer: Michael Knyszek <mkny...@google.com>
Gerrit-CC: Steve Muir <sjm...@google.com>
Gerrit-Attention: Carlos Amedee <car...@golang.org>
Gerrit-Attention: Michael Knyszek <mkny...@google.com>
Gerrit-Comment-Date: Wed, 01 Oct 2025 15:47:43 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
satisfied_requirement
unsatisfied_requirement
open
diffy

Carlos Amedee (Gerrit)

unread,
12:39 PM (10 hours ago) 12:39 PM
to Steve Muir, goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Go LUCI, Cherry Mui, Michael Knyszek, golang-co...@googlegroups.com

Carlos Amedee submitted the change

Change information

Commit message:
[release-branch.go1.25] runtime: initialise debug settings much earlier in startup process

This is necessary specifically to set the value of `debug.decoratemappings`
sufficiently early in the startup sequence that all memory ranges allocated
can be named appropriately using the new Linux-specific naming API
introduced in #71546.

Example output (on ARM64):
https://gist.github.com/9muir/3667654b9c3f52e8be92756219371672

For: #75324
Fixes #75669

Change-Id: Ic0b16233f54a45adef1660c4d0df59af2f5af86a
Reviewed-on: https://go-review.googlesource.com/c/go/+/703476
Auto-Submit: Michael Knyszek <mkny...@google.com>
LUCI-TryBot-Result: Go LUCI <golang...@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Knyszek <mkny...@google.com>
(cherry picked from commit 300d9d2714164e455abc7990d52de9de6b084df1)
Files:
  • A src/runtime/decoratemappings_test.go
  • M src/runtime/export_test.go
  • M src/runtime/proc.go
  • M src/runtime/runtime1.go
  • M src/runtime/set_vma_name_linux.go
  • M src/runtime/set_vma_name_stub.go
Change size: M
Delta: 6 files changed, 109 insertions(+), 14 deletions(-)
Branch: refs/heads/release-branch.go1.25
Submit Requirements:
  • requirement satisfiedCode-Review: +2 by Cherry Mui
  • requirement satisfiedTryBots-Pass: LUCI-TryBot-Result+1 by Go LUCI
Open in Gerrit
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: merged
Gerrit-Project: go
Gerrit-Branch: release-branch.go1.25
Gerrit-Change-Id: Ic0b16233f54a45adef1660c4d0df59af2f5af86a
Gerrit-Change-Number: 708359
Gerrit-PatchSet: 2
Gerrit-Owner: Carlos Amedee <car...@golang.org>
Gerrit-Reviewer: Carlos Amedee <car...@golang.org>
Gerrit-Reviewer: Cherry Mui <cher...@google.com>
Gerrit-Reviewer: Michael Knyszek <mkny...@google.com>
Gerrit-CC: Steve Muir <sjm...@google.com>
open
diffy
satisfied_requirement
Reply all
Reply to author
Forward
0 new messages