go 运行时:lfstack中的规范48位地址错误

nhaq1z21  于 24天前  发布在  Go
关注(0)|答案(2)|浏览(16)

你正在使用的Go版本是什么(go version)?
go版本:go1.16.2 linux/amd64

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

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

$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/ryanh/.cache/go-build"
GOENV="/home/ryanh/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/ryanh/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/ryanh/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/lib/go-1.16"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go-1.16/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.16.2"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build1471403295=/tmp/go-build -gno-record-gcc-switches"

你做了什么?
如果lfstack在设置了最高位的amd64平台上获取到任何指针,那么会抛出一个Assert。
在大多数情况下,这种情况不会发生,因为内核将消耗VA的最高位,留下用户空间的47位VA。
这是一个关于地址规范化的逻辑错误。
检查在这里:https://github.com/golang/go/blob/master/src/runtime/lfstack.go#L28
指针符号扩展在这里:https://github.com/golang/go/blob/master/src/runtime/lfstack_64bit.go#L52
我没有一个基本的应用或环境来重现这个问题。很容易看到这个逻辑错误。

你期望看到什么?
虽然在48位系统上必须通过符号扩展来规范化指针(我甚至不会提到LA57),但lfstack中的检查是错误的,因为它假设符号扩展永远不会发生。因此,它假设永远不会收到一个真正的48位指针。
这种假设在得到带有高位设置的48位指针的环境中被打破。
这只是一个简单的逻辑错误,不应该在这个情况下Assert。

你看到了什么?
在带有高位设置的48位地址上出现了Assert。

5anewei6

5anewei61#

谢谢。请注意,此代码与系统密切相关。您提到的问题是否真的可以在任何现有系统中发生?如果不是,就不必担心了。

fae0ux8s

fae0ux8s2#

目前唯一的真正担忧是,如果有人尝试在启用LA57的英特尔最新服务器平台上运行。这不会向用户空间传递48位(或更高)指针,除非明确要求。否则,它可能只是玩具环境试图像AArch64平台那样使用48位虚拟地址空间。切换CPL上的内存Map会改变。

相关问题