diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-16 19:25:22 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-16 19:25:22 +0000 |
commit | f6ad4dcef54c5ce997a4bad5a6d86de229015700 (patch) | |
tree | 7cfa4e31ace5c2bd95c72b154d15af494b2bcbef /src/runtime/pprof/vminfo_darwin_test.go | |
parent | Initial commit. (diff) | |
download | golang-1.22-f6ad4dcef54c5ce997a4bad5a6d86de229015700.tar.xz golang-1.22-f6ad4dcef54c5ce997a4bad5a6d86de229015700.zip |
Adding upstream version 1.22.1.upstream/1.22.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/runtime/pprof/vminfo_darwin_test.go')
-rw-r--r-- | src/runtime/pprof/vminfo_darwin_test.go | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/src/runtime/pprof/vminfo_darwin_test.go b/src/runtime/pprof/vminfo_darwin_test.go new file mode 100644 index 0000000..8749a13 --- /dev/null +++ b/src/runtime/pprof/vminfo_darwin_test.go @@ -0,0 +1,163 @@ +// Copyright 2023 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. + +//go:build !ios + +package pprof + +import ( + "bufio" + "bytes" + "fmt" + "internal/abi" + "internal/testenv" + "os" + "os/exec" + "strconv" + "strings" + "testing" +) + +func TestVMInfo(t *testing.T) { + var begin, end, offset uint64 + var filename string + first := true + machVMInfo(func(lo, hi, off uint64, file, buildID string) { + if first { + begin = lo + end = hi + offset = off + filename = file + } + // May see multiple text segments if rosetta is used for running + // the go toolchain itself. + first = false + }) + lo, hi, err := useVMMapWithRetry(t) + if err != nil { + t.Fatal(err) + } + if got, want := begin, lo; got != want { + t.Errorf("got %x, want %x", got, want) + } + if got, want := end, hi; got != want { + t.Errorf("got %x, want %x", got, want) + } + if got, want := offset, uint64(0); got != want { + t.Errorf("got %x, want %x", got, want) + } + if !strings.HasSuffix(filename, "pprof.test") { + t.Errorf("got %s, want pprof.test", filename) + } + addr := uint64(abi.FuncPCABIInternal(TestVMInfo)) + if addr < lo || addr > hi { + t.Errorf("%x..%x does not contain function %p (%x)", lo, hi, TestVMInfo, addr) + } +} + +func useVMMapWithRetry(t *testing.T) (hi, lo uint64, err error) { + var retryable bool + for { + hi, lo, retryable, err = useVMMap(t) + if err == nil { + return hi, lo, nil + } + if !retryable { + return 0, 0, err + } + t.Logf("retrying vmmap after error: %v", err) + } +} + +func useVMMap(t *testing.T) (hi, lo uint64, retryable bool, err error) { + pid := strconv.Itoa(os.Getpid()) + testenv.MustHaveExecPath(t, "vmmap") + cmd := testenv.Command(t, "vmmap", pid) + out, cmdErr := cmd.Output() + if cmdErr != nil { + t.Logf("vmmap output: %s", out) + if ee, ok := cmdErr.(*exec.ExitError); ok && len(ee.Stderr) > 0 { + t.Logf("%v: %v\n%s", cmd, cmdErr, ee.Stderr) + } + retryable = bytes.Contains(out, []byte("resource shortage")) + t.Logf("%v: %v", cmd, cmdErr) + if retryable { + return 0, 0, true, cmdErr + } + } + // Always parse the output of vmmap since it may return an error + // code even if it successfully reports the text segment information + // required for this test. + hi, lo, err = parseVmmap(out) + if err != nil { + if cmdErr != nil { + return 0, 0, false, fmt.Errorf("failed to parse vmmap output, vmmap reported an error: %v", err) + } + t.Logf("vmmap output: %s", out) + return 0, 0, false, fmt.Errorf("failed to parse vmmap output, vmmap did not report an error: %v", err) + } + return hi, lo, false, nil +} + +// parseVmmap parses the output of vmmap and calls addMapping for the first r-x TEXT segment in the output. +func parseVmmap(data []byte) (hi, lo uint64, err error) { + // vmmap 53799 + // Process: gopls [53799] + // Path: /Users/USER/*/gopls + // Load Address: 0x1029a0000 + // Identifier: gopls + // Version: ??? + // Code Type: ARM64 + // Platform: macOS + // Parent Process: Code Helper (Plugin) [53753] + // + // Date/Time: 2023-05-25 09:45:49.331 -0700 + // Launch Time: 2023-05-23 09:35:37.514 -0700 + // OS Version: macOS 13.3.1 (22E261) + // Report Version: 7 + // Analysis Tool: /Applications/Xcode.app/Contents/Developer/usr/bin/vmmap + // Analysis Tool Version: Xcode 14.3 (14E222b) + // + // Physical footprint: 1.2G + // Physical footprint (peak): 1.2G + // Idle exit: untracked + // ---- + // + // Virtual Memory Map of process 53799 (gopls) + // Output report format: 2.4 -64-bit process + // VM page size: 16384 bytes + // + // ==== Non-writable regions for process 53799 + // REGION TYPE START END [ VSIZE RSDNT DIRTY SWAP] PRT/MAX SHRMOD PURGE REGION DETAIL + // __TEXT 1029a0000-1033bc000 [ 10.1M 7360K 0K 0K] r-x/rwx SM=COW /Users/USER/*/gopls + // __DATA_CONST 1033bc000-1035bc000 [ 2048K 2000K 0K 0K] r--/rwSM=COW /Users/USER/*/gopls + // __DATA_CONST 1035bc000-103a48000 [ 4656K 3824K 0K 0K] r--/rwSM=COW /Users/USER/*/gopls + // __LINKEDIT 103b00000-103c98000 [ 1632K 1616K 0K 0K] r--/r-SM=COW /Users/USER/*/gopls + // dyld private memory 103cd8000-103cdc000 [ 16K 0K 0K 0K] ---/--SM=NUL + // shared memory 103ce4000-103ce8000 [ 16K 16K 16K 0K] r--/r-SM=SHM + // MALLOC metadata 103ce8000-103cec000 [ 16K 16K 16K 0K] r--/rwx SM=COW DefaultMallocZone_0x103ce8000 zone structure + // MALLOC guard page 103cf0000-103cf4000 [ 16K 0K 0K 0K] ---/rwx SM=COW + // MALLOC guard page 103cfc000-103d00000 [ 16K 0K 0K 0K] ---/rwx SM=COW + // MALLOC guard page 103d00000-103d04000 [ 16K 0K 0K 0K] ---/rwx SM=NUL + + banner := "==== Non-writable regions for process" + grabbing := false + sc := bufio.NewScanner(bytes.NewReader(data)) + for sc.Scan() { + l := sc.Text() + if grabbing { + p := strings.Fields(l) + if len(p) > 7 && p[0] == "__TEXT" && p[7] == "r-x/rwx" { + locs := strings.Split(p[1], "-") + start, _ := strconv.ParseUint(locs[0], 16, 64) + end, _ := strconv.ParseUint(locs[1], 16, 64) + return start, end, nil + } + } + if strings.HasPrefix(l, banner) { + grabbing = true + } + } + return 0, 0, fmt.Errorf("vmmap no text segment found") +} |