-
Notifications
You must be signed in to change notification settings - Fork 17.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
runtime,runtime/pprof: get memory mappings on darwin.
Displaying assembly language has never worked for Apple Silicon macs (see #50891). This change uses mach_vm_region to obtain the necessary VM mappings to allow for locating assembly instructions for a cpu profile. Fixes #50891 Change-Id: Ib968c55a19b481b82f63337276b552f3b18f69d1 Reviewed-on: https://go-review.googlesource.com/c/go/+/503919 Run-TryBot: Cherry Mui <[email protected]> Reviewed-by: Cherry Mui <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: David Chase <[email protected]>
- Loading branch information
1 parent
d50272a
commit b7c826d
Showing
17 changed files
with
464 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// 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. | ||
|
||
// This file is used as input to cgo --godefs (GOOS=arm64 or amd64) to | ||
// generate the types used in viminfo_darwin_{arm64,amd64}.go which are | ||
// hand edited as appropriate, primarily to avoid exporting the types. | ||
|
||
//go:build ignore | ||
|
||
package pprof | ||
|
||
/* | ||
#include <sys/param.h> | ||
#include <mach/vm_prot.h> | ||
#include <mach/vm_region.h> | ||
*/ | ||
import "C" | ||
|
||
type machVMRegionBasicInfoData C.vm_region_basic_info_data_64_t | ||
|
||
const ( | ||
_VM_PROT_READ = C.VM_PROT_READ | ||
_VM_PROT_WRITE = C.VM_PROT_WRITE | ||
_VM_PROT_EXECUTE = C.VM_PROT_EXECUTE | ||
|
||
_MACH_SEND_INVALID_DEST = C.MACH_SEND_INVALID_DEST | ||
|
||
_MAXPATHLEN = C.MAXPATHLEN | ||
) |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// 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. | ||
|
||
package pprof | ||
|
||
import ( | ||
"errors" | ||
) | ||
|
||
// readMapping adds a mapping entry for the text region of the running process. | ||
// It uses the mach_vm_region region system call to add mapping entries for the | ||
// text region of the running process. Note that currently no attempt is | ||
// made to obtain the buildID information. | ||
func (b *profileBuilder) readMapping() { | ||
if !machVMInfo(b.addMapping) { | ||
b.addMappingEntry(0, 0, 0, "", "", true) | ||
} | ||
} | ||
|
||
func readMainModuleMapping() (start, end uint64, exe, buildID string, err error) { | ||
first := true | ||
ok := machVMInfo(func(lo, hi, off uint64, file, build string) { | ||
if first { | ||
start, end = lo, hi | ||
exe, buildID = file, build | ||
} | ||
// May see multiple text segments if rosetta is used for running | ||
// the go toolchain itself. | ||
first = false | ||
}) | ||
if !ok { | ||
return 0, 0, "", "", errors.New("machVMInfo failed") | ||
} | ||
return start, end, exe, buildID, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// 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. | ||
|
||
package pprof | ||
|
||
import ( | ||
"os" | ||
"unsafe" | ||
) | ||
|
||
func isExecutable(protection int32) bool { | ||
return (protection&_VM_PROT_EXECUTE) != 0 && (protection&_VM_PROT_READ) != 0 | ||
} | ||
|
||
// machVMInfo uses the mach_vm_region region system call to add mapping entries | ||
// for the text region of the running process. | ||
func machVMInfo(addMapping func(lo, hi, offset uint64, file, buildID string)) bool { | ||
added := false | ||
var addr uint64 = 0x1 | ||
for { | ||
var memRegionSize uint64 | ||
var info machVMRegionBasicInfoData | ||
// Get the first address and page size. | ||
kr := mach_vm_region( | ||
&addr, | ||
&memRegionSize, | ||
unsafe.Pointer(&info)) | ||
if kr != 0 { | ||
if kr == _MACH_SEND_INVALID_DEST { | ||
// No more memory regions. | ||
return true | ||
} | ||
return added // return true if at least one mapping was added | ||
} | ||
if isExecutable(info.Protection) { | ||
// NOTE: the meaning/value of Offset is unclear. However, | ||
// this likely doesn't matter as the text segment's file | ||
// offset is usually 0. | ||
addMapping(addr, | ||
addr+memRegionSize, | ||
uint64(info.Offset), | ||
regionFilename(addr), | ||
"") | ||
added = true | ||
} | ||
addr += memRegionSize | ||
} | ||
} | ||
|
||
func regionFilename(address uint64) string { | ||
buf := make([]byte, _MAXPATHLEN) | ||
r := proc_regionfilename( | ||
os.Getpid(), | ||
address, | ||
unsafe.SliceData(buf), | ||
int64(cap(buf))) | ||
if r == 0 { | ||
return "" | ||
} | ||
return string(buf[:r]) | ||
} | ||
|
||
// mach_vm_region and proc_regionfilename are implemented by | ||
// the runtime package (runtime/sys_darwin.go). | ||
// | ||
//go:noescape | ||
func mach_vm_region(address, region_size *uint64, info unsafe.Pointer) int32 | ||
|
||
//go:noescape | ||
func proc_regionfilename(pid int, address uint64, buf *byte, buflen int64) int32 |
Oops, something went wrong.