go 在调试/macho时,某些C++符号的前导下划线被去除了,

8ljdwjyq  于 6个月前  发布在  Go
关注(0)|答案(7)|浏览(64)

你正在使用的Go版本是什么( go version )?

$ go version
go version go1.19.5 darwin/arm64

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

是的。自 06e5529 更改以来没有变化。最新的代码在这里:https://github.com/golang/go/blob/master/src/debug/macho/file.go#L503

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

go env 输出

$ go env

GO111MODULE=""

GOARCH="arm64"

GOBIN=""

GOCACHE="/Users/lichengdong/Library/Caches/go-build"

GOENV="/Users/lichengdong/Library/Application Support/go/env"

GOEXE=""

GOEXPERIMENT=""

GOFLAGS=""

GOHOSTARCH="arm64"

GOHOSTOS="darwin"

GOINSECURE=""

GOMODCACHE="/Users/lichengdong/go/pkg/mod"

GONOPROXY=""

GONOSUMDB=""

GOOS="darwin"

GOPATH="/Users/lichengdong/go"

GOPRIVATE=""

GOPROXY=" [https://proxy.golang.org,direct](https://proxy.golang.org,direct) "

GOROOT="/opt/homebrew/Cellar/go/1.19.5/libexec"

GOSUMDB="sum.golang.org"

GOTMPDIR=""

GOTOOLDIR="/opt/homebrew/Cellar/go/1.19.5/libexec/pkg/tool/darwin_arm64"

GOVCS=""

GOVERSION="go1.19.5"

GCCGO="gccgo"

AR="ar"

CC="clang"

CXX="clang++"

CGO_ENABLED="1"

GOMOD="/dev/null"

GOWORK=""

CGO_CFLAGS="-g -O2"

CGO_CPPFLAGS=""

CGO_CXXFLAGS="-g -O2"

CGO_FFLAGS="-g -O2"

CGO_LDFLAGS="-g -O2"

PKG_CONFIG="pkg-config"

GOGCCFLAGS="-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/g4/4_y2t8q179s1n1h40218_3rm0000gn/T/go-build3619303289=/tmp/go-build -gno-record-gcc-switches -fno-common"

你做了什么?

比较一个由C生成的二进制文件,并使用系统 nm/objdump 查看该二进制文件中的符号。同时使用 debug/macho 来转储符号。例如,nm/objdump中的C符号 __GLOBAL__sub_I_main.mm 在 debug/macho 中会被第一个下划线 _ 丢弃。

你期望看到什么?

与工具 nm/objdump 的结果相同

你看到了什么?

nm/objdump 的输出

ruoxqz4g

ruoxqz4g1#

这是不幸的,但我不确定最好的选择是什么。也许我们可以保留下划线,如果有两个前导下划线?总会有一些不准确性,因为最终一个人可以写出一个看起来像Go符号但实际上不是Go符号的符号名称。
您的用例是什么?您能做一些简单的解决方法吗?谢谢。

sqxo8psd

sqxo8psd2#

在我看来,对于像debug/macho这样的包来说,篡改符号名称是一个错误。如果我们希望工具如cmd/nm和cmd/objdump在输出时省略前导下划线,那么应该在其他地方处理,也许可以使用一个格式列表来表示需要添加前导下划线的格式。
例如,对于windows-386,所有符号都有一个前导下划线,但据我所知,debug/pe并没有去除这个前导下划线。

idfiyjo8

idfiyjo83#

我们可以将debug/macho更改为不去除前导下划线。我们还可以让cmd/nm和cmd/objdump也不做这个操作。这样,它将与二进制文件符号表中的符号名称相同。不确定这是否会破坏任何人(因为对于一些以前不存在的符号,它仍然会有一个前导下划线)。

5lwkijsr

5lwkijsr4#

This is unfortunate, but I'm not sure what the best option is. Maybe we could keep the underscore if there are two leading underscores? There is always some inaccuracy, as in the end one can write a symbol name that looks like a Go symbol but not really a Go symbol.
What is your use case? Is there a simple workaround that you can do? Thanks.
A normal C++ program with static class would generate symbols like GLOBAL__sub__I*, I didn't try any workaround. But I think if compare symbol name with "GLOBAL__sub__I" may work for C++ static class/variable symbols.
However, I am not sure if this way breaks other tools, I am not a C++ expert. :-(

k4ymrczo

k4ymrczo5#

是的。我相信当人们编译像这样的#33808程序时,他们会感到困惑。他们会发现一些符号(导出的符号?)有一个前导_,这与源代码中的名称不同。

我认为,我们可能需要区分golang与其他语言(如C++)的符号。然后分别处理这些情况。

hl0ma9xz

hl0ma9xz6#

1.21太晚了,我会在Go 1.22中做这件事。(这是一个用户可见的行为变化,所以在冻结的后期这样做可能不是一个好主意。)

mcdcgff0

mcdcgff07#

在1.22冻结之前,我错过了这个。我会在下一个周期的早期进行这个操作。

相关问题