go 运行时/竞态:在ppc64le上,竞态检测器截断命令行参数,

shyt4zoc  于 4个月前  发布在  Go
关注(0)|答案(5)|浏览(58)

当以下程序在启用竞态检测器的情况下运行时,它会在 "" 参数处截断命令行参数列表。特别是,这防止了在 ppc64le 上使用启用竞态检测器的 cmd/compile,因为 cmd/go 通常传递 -D ""。我只在 linux/ppc64le 上看到这个问题。我无法在 linux/amd64 上重现这个问题。

$ go run hi.go -- one two "" three four
["/tmp/go-build2867456842/b001/exe/hi" "--" "one" "two" "" "three" "four"]
["one" "two" "" "three" "four"]

$ go run -race hi.go -- one two "" three four
["/tmp/go-build2206806436/b001/exe/hi" "--" "one" "two"]
["one" "two"]

package main

import (
"flag"
"fmt"
"os"
)

func main() {
fmt.Printf("%q\n", os.Args)
flag.Parse()
fmt.Printf("%q\n", flag.Args())
}


/cc @dvyukov
ql3eal8s

ql3eal8s1#

https://golang.org/cl/286173提到了这个问题:[dev.regabi] cmd/go: workaround -race issue on ppc64le

8yoxcaq7

8yoxcaq72#

仅猜测:在某些架构中,TSAN可能会重新执行程序(例如,由于它需要特定的内存布局而禁用ASLR)。重新执行可能会消耗参数。也许您可以使用strace来查看它是否重新执行?机器上ulimit -a的输出是什么?

jdg4fx2g

jdg4fx2g3#

也许你可以使用strace来查看它是否重新执行?
这确实看起来像是罪魁祸首:

$ strace -f ./hi one two "" three four |& grep exec
execve("./hi", ["./hi", "one", "two", "", "three", "four"], 0x7fffe4ef9d90 /* 40 vars */) = 0
execve("/proc/self/exe", ["./hi", "one", "two"], 0x7fff96060000 /* 40 vars */) = 0

在机器上运行ulimit -a的输出是什么?

$ ulimit -a
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 246242
max locked memory       (kbytes, -l) 65536
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 246242
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
envsm3lx

envsm3lx4#

可能是ASLR(地址空间布局随机化)的问题。你可以尝试禁用ASLR吗?
这可能是TSAN(线程本地存储抽象)中重新执行代码的错误。

0g0grzrc

0g0grzrc5#

是的,看起来像是来自TSAN绕过ASLR的工作:

$ ./hi one two "" three four
["./hi" "one" "two"]
["one" "two"]

$ setarch `uname -m` -R ./hi one two "" three four
["./hi" "one" "two" "" "three" "four"]
["one" "two" "" "three" "four"]

相关问题