Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime: mangled function names for method value wrapper #64985

Open
vault-thirteen opened this issue Jan 6, 2024 · 11 comments
Open

runtime: mangled function names for method value wrapper #64985

vault-thirteen opened this issue Jan 6, 2024 · 11 comments
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@vault-thirteen
Copy link

Go version

go version go1.20.12 windows/amd64

Output of go env in your module/workspace:

set GO111MODULE=on
set GOARCH=amd64              
set GOBIN=                    
set GOCACHE=H:\Temp\_Go_\Cache
set GOENV=C:\Users\***\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=G:\Projects\Go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=G:\Projects\Go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=H:\Program Files\Go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=H:\Program Files\Go\pkg\tool\windows_amd64
set GOVCS=
set GOVERSION=go1.20.12
set GCCGO=gccgo
set GOAMD64=v1
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=0
set GOMOD=G:\Projects\Go\src\github.com\vault-thirteen\SimpleBB\go.mod
set GOWORK=
set CGO_CFLAGS=-O2 -g
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-O2 -g
set CGO_FFLAGS=-O2 -g
set CGO_LDFLAGS=-O2 -g
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -fno-caret-diagnostics -Qunused-arguments -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=C:\Users\***\AppData\Local\Temp\go-build***=/tmp/go-build -gno-record-gcc-switches

What did you do?

I get a name of a function with the following code:

fullName := runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name()

For the method Ping of a Server class (type) it returns the following name:
github.com/vault-thirteen/SimpleBB/pkg/ACM.(*Server).Ping-fm

For some reason a -fm postfix is added to the function's full name.

When I tested the package which gets name of a function locally -- there was no -fm postfix and all the tests of this code pass normally.

  1. Why does a name contain the minus (hyphen) sign which can not be used for identifiers in Go language ?

  2. What does the fm mean ?

  3. How do I get a normal function name without -fm postfix ?

What did you see happen?

I saw github.com/vault-thirteen/SimpleBB/pkg/ACM.(*Server).Ping-fm.

What did you expect to see?

I expected to see the same function name as in tests of the method, i.e. a normal name of a function without any postfixes.

@Jorropo
Copy link
Member

Jorropo commented Jan 6, 2024

Similar to #24488

@seankhliao seankhliao changed the title Runtime function name is distorted runtime: function name is distorted Jan 6, 2024
@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Jan 6, 2024
@seankhliao
Copy link
Member

seankhliao commented Jan 6, 2024

what's f

@vault-thirteen
Copy link
Author

what's f

I suppose that it is a question.
f is simply a function.

A simple test demonstrating this effect can be found here:
https://github.com/vault-thirteen/JSON-RPC-M1/blob/main/RpcFunction_test.go#L18

I had to add another stage of function name parsing into the tested function located here:
https://github.com/vault-thirteen/JSON-RPC-M1/blob/main/RpcFunction.go#L42

If I do not split the name with a hyphen, I get a strange function name like Abc-fm which is not what I expect when I pass a function named Abc.

@mauri870
Copy link
Member

mauri870 commented Jan 6, 2024

I think this is expected. The compiler inserts the -fm suffix as the closure name (that is the way methods are implemented) and the suffix prevents collisions with existing function names. The function name has no real use outside of debuggers and maybe FuncForPC.

@vault-thirteen
Copy link
Author

@mauri870 ,
The function which I tested is not a closure, it is a class method, or a type method if we speak about Go language.
https://github.com/vault-thirteen/JSON-RPC-M1/blob/main/RpcFunction_test.go#L11C22-L11C22

@mauri870
Copy link
Member

mauri870 commented Jan 6, 2024

@vault-thirteen The way method sets are implemented, the -fm suffix is added by the compiler to differenciate between the same method in T.M and (*T).M, so they have distinct method symbols. See https://go.dev/play/p/fq0dFnO9j_S

@vault-thirteen
Copy link
Author

@mauri870,
Is this a documented feature of Go language ?

@mauri870
Copy link
Member

mauri870 commented Jan 6, 2024

Not to my knowledge. It seems a rather internal detail about the compiler implementation. For instance, gccgo outputs the following for the program I linked above:

T.M: main.go..thunk0
(*T).M: main.go..thunk1

Reading the spec it only mentions that method sets must be unique.

Maybe the compiler folks can shine some line in here.

/cc @golang/compiler

@vault-thirteen
Copy link
Author

vault-thirteen commented Jan 6, 2024

@mauri870 , thank you for the information.

For me it looks like Go language needs to introduce method overriding as in C++ and make a stable API and ABI, so that we do not see all these strange things any more. Who knows what will the postfix -fm be tomorrow and will it be separated by a hyphen or a tilda or maybe something else ...

@mdempsky
Copy link
Member

mdempsky commented Jan 6, 2024

The -fm suffix indicates a method value wrapper. (The suffix predates my involvement in the Go compiler, so I'm not sure what significance the letters "fm" have.)

I don't believe we currently guarantee what FuncForPC returns on method values. I'm open to defining it. (/cc @ianlancetaylor @alandonovan for gccgo and x/tools/go/ssa.)

Who knows what will the postfix -fm be tomorrow and will it be separated by a hyphen or a tilda or maybe something else ...

While we reserve the right to change internal symbol mangling, it's not something we do casually. We know it risks churn for end users. (Eg, I believe gc has used the -fm suffix since method values were added in Go 1.1.)

@vault-thirteen
Copy link
Author

@mdempsky , thank you for the details.

@dmitshur dmitshur added this to the Backlog milestone Jan 9, 2024
@dmitshur dmitshur added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jan 9, 2024
@seankhliao seankhliao changed the title runtime: function name is distorted runtime: mangled function names for method value wrapper Jan 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
Development

No branches or pull requests

7 participants