Skip to content

cmd/go: spurious error message when external linking a pure Go program #31544

Closed
@cherrymui

Description

@cherrymui

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

tip (3235f7c)

Does this issue reproduce with the latest release?

Yes, happens with Go 1.11, 1.12, and tip, but not with Go 1.10.

What operating system and processor architecture are you using (go env)?

linux/amd64

What did you do?

$ mkdir -p /tmp/src/hello
$ cat >hello.go
package main
func main() { println("hello") }
$ GO111MODULE=off GOPATH=/tmp go build -ldflags=-linkmode=external
# hello
loadinternal: cannot find runtime/cgo
$ echo $?
0
$ ./hello
hello

When using external linking for a pure Go program, the linker prints loadinternal: cannot find runtime/cgo message. The linking actually succeeded, and the generated binary works fine.

What did you expect to see?

No error message, like with Go 1.10.

$ GOPATH=/tmp go1.10 build -ldflags=-linkmode=external 
$ ./hello 
hello

What did you see instead?

Spurious loadinternal: cannot find runtime/cgo error message.

Activity

cherrymui

cherrymui commented on Apr 18, 2019

@cherrymui
MemberAuthor

This also happens in module mode:

$ go mod init hello
go: creating new go.mod: module hello
$ GO111MODULE=on go build -ldflags=-linkmode=external 
# hello
loadinternal: cannot find runtime/cgo

But it does not happen if the file name (hello.go) is given explicitly.

$ go build -ldflags=-linkmode=external hello.go 
$
changed the title [-]cmd/go or cmd/link: spurious error message when external linking a pure Go program[/-] [+]cmd/go: spurious error message when external linking a pure Go program[/+] on Apr 22, 2019
added this to the Go1.13 milestone on Apr 22, 2019
added
NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.
on Apr 22, 2019
julieqiu

julieqiu commented on Apr 22, 2019

@julieqiu
Member
bcmills

bcmills commented on May 8, 2019

@bcmills
Contributor

I can reproduce the failure. I'm bisecting it now to try to get some idea of how it broke.

self-assigned this
on May 8, 2019
bcmills

bcmills commented on May 8, 2019

@bcmills
Contributor

git bisect points to CL 129059 (CC @rsc @alandonovan).

bcmills

bcmills commented on May 8, 2019

@bcmills
Contributor

This is a result of the -ldflags=-linkmode=external flag now (correctly) being passed when compiling the hello package, which reveals a typestate bug in load.PackagesAndErrors.

The decision in the LinkerDeps function about whether to add the runtime/cgo dependency is based on whether the -ldflags=-linkmode=external flag is set for the package, which itself depends on whether CmdlinePkg flag is set:

match := func(p *Package) bool { return p.Internal.CmdlinePkg || p.Internal.CmdlineFiles } // default predicate with no pattern

That field is set after the call to loadImport:

p := loadImport(pre, pkg, base.Cwd, nil, &stk, nil, 0)
p.Match = append(p.Match, m.Pattern)
p.Internal.CmdlinePkg = true

However, by that point loadImport has already called load on the package:

p.load(stk, bp, err)

...and load is what's supposed to figure out the implicit linker dependencies:

for _, dep := range LinkerDeps(p) {

rsc

rsc commented on May 9, 2019

@rsc
Contributor

@cherrymui, unless this is important for you for some reason, we'd like to postpone the fix to Go 1.14. It's subtle code.

/cc @bcmills

modified the milestones: Go1.13, Go1.14 on May 9, 2019
gopherbot

gopherbot commented on May 9, 2019

@gopherbot
Contributor

Change https://golang.org/cl/176217 mentions this issue: cmd/go/internal/work: set CmdlinePkg in loadImport instead of after

cherrymui

cherrymui commented on May 9, 2019

@cherrymui
MemberAuthor

@cherrymui, unless this is important for you for some reason, we'd like to postpone the fix to Go 1.14. It's subtle code.

Sure, it is fine to postpone.

removed this from the Go1.14 milestone on Oct 9, 2019

53 remaining items

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeGoCommandcmd/goNeedsFixThe path to resolution is known, but the work has not been done.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @rsc@jayconrod@dmitshur@dr2chase@ianlancetaylor

        Issue actions

          cmd/go: spurious error message when external linking a pure Go program · Issue #31544 · golang/go