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

cmd/compile: user symbols can be in reserved namespace #37762

Open
Pr0Ger opened this issue Mar 9, 2020 · 9 comments
Open

cmd/compile: user symbols can be in reserved namespace #37762

Pr0Ger opened this issue Mar 9, 2020 · 9 comments
Milestone

Comments

@Pr0Ger
Copy link

@Pr0Ger Pr0Ger commented Mar 9, 2020

What version of Go are you using (go version)?

$ go version
go version go1.14 darwin/amd64

What did you do?

package main

import "debug/gosym"

func main()  {
	s1 := gosym.Sym{Name: "go.uber.org/zap/zapcore.(*CheckedEntry).Write"}

	println(s1.PackageName())
}

What did you expect to see?

go.uber.org/zap/zapcore

What did you see instead?

empty string

I see problem is right here but since I'm not aware how linker uses these prefixes I can't figure out how to properly fix this condition

// A prefix of "type." and "go." is a compiler-generated symbol that doesn't belong to any package.
// See variable reservedimports in cmd/compile/internal/gc/subr.go
if strings.HasPrefix(name, "go.") || strings.HasPrefix(name, "type.") {
return ""
}

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Mar 9, 2020

The debug/gosym package is intended to be used to read object files generated by the compiler. It's not intended to be used by creating your own instances of gosym.Sym.

Can you show us a complete program that demonstrates this problem when opening an object generated by the compiler? Please also include the sources for the object that you want to open. Thanks.

@Pr0Ger

This comment has been minimized.

Copy link
Author

@Pr0Ger Pr0Ger commented Mar 9, 2020

Yeah, sure (go.uber.org/zap is a public available library):

package main

import (
	"debug/gosym"
	"debug/macho"
	"fmt"
	"os"
	"strings"

	"go.uber.org/zap"
)

func main() {
	logger, _ := zap.NewDevelopment()
	logger.Debug("using logger just a little bit")

	executable, _ := os.Executable()
	exe, _ := macho.Open(executable)

	pclndat, _ := exe.Section("__gopclntab").Data()
	symTabRaw, _ := exe.Section("__gosymtab").Data()

	pcln := gosym.NewLineTable(pclndat, exe.Section("__text").Addr)
	symTab, _ := gosym.NewTable(symTabRaw, pcln)
	for _, funk := range symTab.Funcs {
		if strings.Contains(funk.Name, "go.uber.org") {
			fmt.Printf("%s -> %s\n", funk.Name, funk.PackageName())
		}
	}
}

And output (just a few lines):

❯ go run test.go
go: finding module for package go.uber.org/zap
go: downloading go.uber.org/zap v1.14.0
go: found go.uber.org/zap in go.uber.org/zap v1.14.0
2020-03-09T22:16:31.280+0300	DEBUG	test_package_name/test.go:15	using logger just a little bit
go.uber.org/zap/buffer.(*Buffer).AppendString ->
go.uber.org/zap/buffer.(*Buffer).AppendBool ->
...
@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Mar 9, 2020

Thanks. If user packages can be in the compiler-reserved "go." namespace, that seems like a potential problem.

CC @griesemer @mdempsky @josharian @randall77

@ianlancetaylor ianlancetaylor added this to the Go1.15 milestone Mar 9, 2020
@ianlancetaylor ianlancetaylor changed the title debug/gosym: PackageName() cmd/compile: user symbols can be in reserved namespace Mar 9, 2020
@mdempsky

This comment has been minimized.

Copy link
Member

@mdempsky mdempsky commented Mar 9, 2020

Bitten again by our ad hoc symbol mangling rules. :(

I think a short-term workaround could be debug/gosym only checks for "go." and "type." when it can't find a '/'. I don't think the compiler ever generates go.* or type.* symbols that contain a /.

This would still cause problems for top-level user package paths like "go.mystuff" (as opposed to "go.mystuff/dir"). Not sure how to best address that off hand.

Edit: Nevermind, I'm mistaken:

$ nm $(go tool -n compile) | grep 'go\..*/' | head -1
0000000000d9aca0 R go.itab.*cmd/compile/internal/gc.blockHeap,container/heap.Interface
@cuonglm

This comment has been minimized.

Copy link
Contributor

@cuonglm cuonglm commented Mar 11, 2020

Can we change go. to go.. instead for compiler generated symbols?

@cuonglm

This comment has been minimized.

Copy link
Contributor

@cuonglm cuonglm commented Mar 18, 2020

Can we change go. to go.. instead for compiler generated symbols?

Seems doable, I make a quick change to go.itab -> go..itab and it's compiled ok and test passed.

@odeke-em

This comment has been minimized.

Copy link
Member

@odeke-em odeke-em commented Mar 28, 2020

Some 2 years ago, there was a somewhat similar issue #25113 reported and fixed by @aarzilli.
We had clashes with userland variables that collided with compiler generated names such as statictmp_0, and we had to rename from statictmp -> .stmp, from @josharian's suggestion in CL https://go-review.googlesource.com/c/go/+/142497. Seems like a similar mangling scheme could help here, as @cuonglm suggested in #37762 (comment), thank you!

@gopherbot

This comment has been minimized.

Copy link

@gopherbot gopherbot commented Mar 29, 2020

Change https://golang.org/cl/226282 mentions this issue: cmd/compile,link: use "go.." for compiler genereated types

@gopherbot

This comment has been minimized.

Copy link

@gopherbot gopherbot commented Mar 29, 2020

Change https://golang.org/cl/226283 mentions this issue: debug/gosym: correct checking condition for compiler generated symbols

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
6 participants
You can’t perform that action at this time.