Skip to content

cmd/go: Go 1.8.x cannot build executables for darwin_arm and darwin_arm64 on macOS, but Go 1.7.x could #20456

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

Closed
akutz opened this issue May 22, 2017 · 10 comments
Labels
FrozenDueToAge help wanted mobile Android, iOS, and x/mobile NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Darwin
Milestone

Comments

@akutz
Copy link

akutz commented May 22, 2017

The Problem

Go 1.7.x can cross-compile binaries for darwin_arm and darwin_arm64 on macOS, but Go 1.8.x cannot.

The Project

The test project is a simple "Hello, world" application.

The Files

$ ls
total 8
drwxr-xr-x+  3 akutz  staff   102B May 20 20:19 ./
drwxr-xr-x+ 27 akutz  staff   918B May 20 19:36 ../
-rw-r--r--+  1 akutz  staff   122B May 20 19:11 main.go

The Program

$ cat main.go
package main

import (
    "fmt"
    "runtime"
)

func main() {
    fmt.Printf("%s_%s\n", runtime.GOOS, runtime.GOARCH)
}

Go 1.7.4

Print the Go environment

$ GOARCH=arm $HOME/.go/1.7.4/bin/go env
GOARCH="arm"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/akutz/Projects/go"
GORACE=""
GOROOT="/Users/akutz/.go/1.7.4"
GOTOOLDIR="/Users/akutz/.go/1.7.4/pkg/tool/darwin_amd64"
CC="clang"
GOGCCFLAGS="-fPIC -marm -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/48/52fjq9r10zx3gnm7j57th0500000gn/T/go-build169705512=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="0"

Print the Go version

$ $HOME/.go/1.7.4/bin/go version
go version go1.7.4 darwin/amd64

Build the binary (Works)

$ env GOARCH=arm $HOME/.go/1.7.4/bin/go build -o hello.darwin_arm .

Reproduce in one line

The following one-liner can reproduce this test case with a clean Go 1.7.5 environment (example output):

GOARCH=arm && \
  cd $(mktemp -d) && \
  mkdir -p gopath/src/hello goroot && \
  cd goroot && \
  curl -SLO https://storage.googleapis.com/golang/go1.7.5.darwin-amd64.tar.gz && \
  tar xzf go1.7.5.darwin-amd64.tar.gz && \
  cd ../gopath/src/hello && \
  printf "package main\n\n" > main.go && \
  printf "import (\n\t\"fmt\"\n\t\"runtime\"\n)\n\n" >> main.go && \
  printf "func main() {\n\t" >> main.go && \
  echo 'fmt.Printf("%s_%s\n", runtime.GOOS, runtime.GOARCH)' >> main.go && \
  printf "}\n" >> main.go && \
  cd ../../.. && \
  echo && echo && \
  env GOROOT=$(pwd)/goroot/go \
      GOPATH=$(pwd)/gopath \
      goroot/go/bin/go version && \
  echo && echo && \
  env GOROOT=$(pwd)/goroot/go \
      GOPATH=$(pwd)/gopath \
      GOARCH=$GOARCH \
      goroot/go/bin/go env && \
  echo && echo && \
  env GOROOT=$(pwd)/goroot/go \
      GOPATH=$(pwd)/gopath \
      GOARCH=$GOARCH \
      goroot/go/bin/go build -work -x -ldflags '-v' -o hello.$GOARCH hello && \
  echo && echo && \
  file hello.$GOARCH

Verify the binary's architecture

$ file hello.darwin_arm
hello.darwin_arm: Mach-O executable arm_v7

Go 1.8.1

Print the Go environment

$ GOARCH=arm $HOME/.go/1.8.1/bin/go env
GOARCH="arm"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/akutz/Projects/go"
GORACE=""
GOROOT="/Users/akutz/.go/1.8.1"
GOTOOLDIR="/Users/akutz/.go/1.8.1/pkg/tool/darwin_amd64"
GCCGO="gccgo"
GOARM=""
CC="clang"
GOGCCFLAGS="-fPIC -marm -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/48/52fjq9r10zx3gnm7j57th0500000gn/T/go-build956504617=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="0"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"

Print the Go version

$ $HOME/.go/1.8.1/bin/go version
go version go1.8.1 darwin/amd64

Build the binary (Fails)

$ env GOARCH=arm $HOME/.go/1.8.1/bin/go build -o hello.darwin_arm .
# github.com/akutz/hello
warning: unable to find runtime/cgo.a
/Users/akutz/.go/1.8.1/pkg/tool/darwin_amd64/link: running clang failed: exit status 1
ld: warning: ignoring file /var/folders/48/52fjq9r10zx3gnm7j57th0500000gn/T/go-link-476535744/go.o, file was built for armv7 which is not the architecture being linked (x86_64): /var/folders/48/52fjq9r10zx3gnm7j57th0500000gn/T/go-link-476535744/go.o
Undefined symbols for architecture x86_64:
  "_main", referenced from:
     implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Build the binary with -ldflags '-v' (Fails)

$ env GOARCH=arm $HOME/.go/1.8.1/bin/go build -ldflags '-v' -o hello.darwin_arm .
# github.com/akutz/hello
HEADER = -H1 -T0x2000 -D0x0 -R0x1000
searching for runtime.a in $WORK/runtime.a
searching for math.a in $WORK/math.a
searching for runtime/cgo.a in $WORK/runtime/cgo.a
searching for runtime/cgo.a in /Users/akutz/.go/1.8.1/pkg/darwin_arm/runtime/cgo.a
warning: unable to find runtime/cgo.a
 0.00 deadcode
 0.01 pclntab=248931 bytes, funcdata total 33020 bytes
 0.01 dodata
 0.01 symsize = 0
 0.01 symsize = 0
 0.01 reloc
 0.02 reloc
 0.02 asmb
 0.02 datblk
 0.02 sym
 0.02 header
 0.04 host link: "clang" "-marm" "-gdwarf-2" "-Wl,-headerpad,1144" "-Wl,-no_pie" "-Wl,-pagezero_size,4000000" "-o" "/var/folders/48/52fjq9r10zx3gnm7j57th0500000gn/T/go-build747006055/github.com/akutz/hello/_obj/exe/a.out" "-Qunused-arguments" "/var/folders/48/52fjq9r10zx3gnm7j57th0500000gn/T/go-link-278262128/go.o"
/Users/akutz/.go/1.8.1/pkg/tool/darwin_amd64/link: running clang failed: exit status 1
ld: warning: ignoring file /var/folders/48/52fjq9r10zx3gnm7j57th0500000gn/T/go-link-278262128/go.o, file was built for armv7 which is not the architecture being linked (x86_64): /var/folders/48/52fjq9r10zx3gnm7j57th0500000gn/T/go-link-278262128/go.o
Undefined symbols for architecture x86_64:
  "_main", referenced from:
     implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Reproduce in one line

The following one-liner can reproduce this test case with a clean Go 1.8.1 environment (example output):

GOARCH=arm && \
  cd $(mktemp -d) && \
  mkdir -p gopath/src/hello goroot && \
  cd goroot && \
  curl -SLO https://storage.googleapis.com/golang/go1.8.1.darwin-amd64.tar.gz && \
  tar xzf go1.8.1.darwin-amd64.tar.gz && \
  cd ../gopath/src/hello && \
  printf "package main\n\n" > main.go && \
  printf "import (\n\t\"fmt\"\n\t\"runtime\"\n)\n\n" >> main.go && \
  printf "func main() {\n\t" >> main.go && \
  echo 'fmt.Printf("%s_%s\n", runtime.GOOS, runtime.GOARCH)' >> main.go && \
  printf "}\n" >> main.go && \
  cd ../../.. && \
  echo && echo && \
  env GOROOT=$(pwd)/goroot/go \
      GOPATH=$(pwd)/gopath \
      goroot/go/bin/go version && \
  echo && echo && \
  env GOROOT=$(pwd)/goroot/go \
      GOPATH=$(pwd)/gopath \
      GOARCH=$GOARCH \
      goroot/go/bin/go env && \
  echo && echo && \
  env GOROOT=$(pwd)/goroot/go \
      GOPATH=$(pwd)/gopath \
      GOARCH=$GOARCH \
      goroot/go/bin/go build -work -x -ldflags '-v' -o hello.$GOARCH hello
@akutz
Copy link
Author

akutz commented May 22, 2017

FWIW, based on the output of go env, I believe this all has something to do with Go 1.8's introduction of plug-ins and somewhat automated Cgo logic.

@bradfitz bradfitz changed the title Go 1.8.x cannot build executables for darwin_arm and darwin_arm64 on macOS, but Go 1.7.x could cmd/go: Go 1.8.x cannot build executables for darwin_arm and darwin_arm64 on macOS, but Go 1.7.x could May 22, 2017
@bradfitz bradfitz added this to the Go1.9Maybe milestone May 22, 2017
@bradfitz bradfitz added help wanted NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels May 22, 2017
@bradfitz
Copy link
Contributor

/cc @ianlancetaylor

@bradfitz
Copy link
Contributor

@akutz, does it work if you set CGO_ENABLED=0 explicitly? Do you need cgo support in your actual code?

@akutz
Copy link
Author

akutz commented May 22, 2017

Hi @bradfitz,

It does not work if I set CGO_ENABED=0. Not even if I build Go from source with CGO_ENABLED=0. As I said, I believe it has to do with the Go 1.8 plug-ins, something I do not think setting CGO_ENABLED=0 actually affects?

FWIW, In my actual product I wasn't even aware I was using Cgo, but it appeared I was in a transitive dependency:

$ for pkg in \
>   $(GOARCH=arm go list -f '{{join .Deps "\n"}}' "github.com/codedellemc/libstorage/cli/lsx/lsx-darwin" | \
>     grep 'github.com/codedellemc/libstorage'); do \
>   pkg=$(echo "$pkg" | cut -c35-) && \
>   for f in $(find "$(echo "$GOPATH" | awk -F: '{print $1}')/src/github.com/codedellemc/libstorage/${pkg}" -name "*.go" -type f); do \
>     if grep 'import "C"' "$f" > /dev/null 2>&1; then \
>       echo $f; \
>     fi; \
>   done; \
> done

/Users/akutz/Projects/go/src/github.com/codedellemc/libstorage/vendor/golang.org/x/sys/unix/types_darwin.go
/Users/akutz/Projects/go/src/github.com/codedellemc/libstorage/vendor/golang.org/x/sys/unix/types_dragonfly.go
/Users/akutz/Projects/go/src/github.com/codedellemc/libstorage/vendor/golang.org/x/sys/unix/types_freebsd.go
/Users/akutz/Projects/go/src/github.com/codedellemc/libstorage/vendor/golang.org/x/sys/unix/types_linux.go
/Users/akutz/Projects/go/src/github.com/codedellemc/libstorage/vendor/golang.org/x/sys/unix/types_netbsd.go
/Users/akutz/Projects/go/src/github.com/codedellemc/libstorage/vendor/golang.org/x/sys/unix/types_openbsd.go
/Users/akutz/Projects/go/src/github.com/codedellemc/libstorage/vendor/golang.org/x/sys/unix/types_solaris.go

However, for the example I outlined above in the issue description, I absolutely was not, at least not via non-Stdlib dependencies. For stdlib there is still Cgo in play:

Example from above

$ pwd
/Users/akutz/Projects/go/src/hello

[0]akutz@pax:hello$ cat main.go
package main

import (
    "fmt"
    "runtime"
)

func main() {
    fmt.Printf("%s_%s\n", runtime.GOOS, runtime.GOARCH)
}

Go 1.7.4 Stdlib Cgo Dependencies for GOARCH=darwin GOOS=arm

$ for pkg in $(GOARCH=arm /Users/akutz/.go/1.7.4/bin/go list -f '{{join .Deps "\n"}}' "hello"); do \
>   for f in $(find "/Users/akutz/.go/1.7.4/src/${pkg}" -name "*.go" -type f); do \
>     if grep 'import "C"' "$f" > /dev/null 2>&1; then \
>       echo $f; \
>     fi; \
>   done; \
> done;

/Users/akutz/.go/1.7.4/src/os/user/getgrouplist_darwin.go
/Users/akutz/.go/1.7.4/src/os/user/getgrouplist_unix.go
/Users/akutz/.go/1.7.4/src/os/user/listgroups_unix.go
/Users/akutz/.go/1.7.4/src/os/user/lookup_unix.go
/Users/akutz/.go/1.7.4/src/runtime/cgo/cgo.go
/Users/akutz/.go/1.7.4/src/runtime/defs1_linux.go
/Users/akutz/.go/1.7.4/src/runtime/defs2_linux.go
/Users/akutz/.go/1.7.4/src/runtime/defs3_linux.go
/Users/akutz/.go/1.7.4/src/runtime/defs_arm_linux.go
/Users/akutz/.go/1.7.4/src/runtime/defs_darwin.go
/Users/akutz/.go/1.7.4/src/runtime/defs_dragonfly.go
/Users/akutz/.go/1.7.4/src/runtime/defs_freebsd.go
/Users/akutz/.go/1.7.4/src/runtime/defs_linux.go
/Users/akutz/.go/1.7.4/src/runtime/defs_netbsd.go
/Users/akutz/.go/1.7.4/src/runtime/defs_netbsd_386.go
/Users/akutz/.go/1.7.4/src/runtime/defs_netbsd_amd64.go
/Users/akutz/.go/1.7.4/src/runtime/defs_netbsd_arm.go
/Users/akutz/.go/1.7.4/src/runtime/defs_openbsd.go
/Users/akutz/.go/1.7.4/src/runtime/defs_solaris.go
/Users/akutz/.go/1.7.4/src/runtime/defs_solaris_amd64.go
/Users/akutz/.go/1.7.4/src/runtime/defs_windows.go
/Users/akutz/.go/1.7.4/src/runtime/msan/msan.go
/Users/akutz/.go/1.7.4/src/runtime/race/race.go
/Users/akutz/.go/1.7.4/src/runtime/race/testdata/cgo_test_main.go
/Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/aprof.go
/Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/callback.go
/Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/cgo.go
/Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/deadlock.go
/Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/dll_windows.go
/Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/dropm.go
/Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/exec.go
/Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/pprof.go
/Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/threadpanic.go
/Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/threadpprof.go
/Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/threadprof.go
/Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/traceback.go
/Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/tracebackctxt.go
/Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/windows/win.go
/Users/akutz/.go/1.7.4/src/syscall/types_darwin.go
/Users/akutz/.go/1.7.4/src/syscall/types_dragonfly.go
/Users/akutz/.go/1.7.4/src/syscall/types_freebsd.go
/Users/akutz/.go/1.7.4/src/syscall/types_linux.go
/Users/akutz/.go/1.7.4/src/syscall/types_netbsd.go
/Users/akutz/.go/1.7.4/src/syscall/types_openbsd.go
/Users/akutz/.go/1.7.4/src/syscall/types_solaris.go

Go 1.8.1 Stdlib Cgo Dependencies for GOARCH=darwin GOOS=arm

$ for pkg in $(GOARCH=arm /Users/akutz/.go/1.8.1/bin/go list -f '{{join .Deps "\n"}}' "hello"); do \
>   for f in $(find "/Users/akutz/.go/1.8.1/src/${pkg}" -name "*.go" -type f); do \
>     if grep 'import "C"' "$f" > /dev/null 2>&1; then \
>       echo $f; \
>     fi; \
>   done; \
> done;

/Users/akutz/.go/1.8.1/src/os/user/getgrouplist_darwin.go
/Users/akutz/.go/1.8.1/src/os/user/getgrouplist_unix.go
/Users/akutz/.go/1.8.1/src/os/user/listgroups_unix.go
/Users/akutz/.go/1.8.1/src/os/user/lookup_unix.go
/Users/akutz/.go/1.8.1/src/runtime/cgo/cgo.go
/Users/akutz/.go/1.8.1/src/runtime/defs1_linux.go
/Users/akutz/.go/1.8.1/src/runtime/defs2_linux.go
/Users/akutz/.go/1.8.1/src/runtime/defs3_linux.go
/Users/akutz/.go/1.8.1/src/runtime/defs_arm_linux.go
/Users/akutz/.go/1.8.1/src/runtime/defs_darwin.go
/Users/akutz/.go/1.8.1/src/runtime/defs_dragonfly.go
/Users/akutz/.go/1.8.1/src/runtime/defs_freebsd.go
/Users/akutz/.go/1.8.1/src/runtime/defs_linux.go
/Users/akutz/.go/1.8.1/src/runtime/defs_netbsd.go
/Users/akutz/.go/1.8.1/src/runtime/defs_netbsd_386.go
/Users/akutz/.go/1.8.1/src/runtime/defs_netbsd_amd64.go
/Users/akutz/.go/1.8.1/src/runtime/defs_netbsd_arm.go
/Users/akutz/.go/1.8.1/src/runtime/defs_openbsd.go
/Users/akutz/.go/1.8.1/src/runtime/defs_solaris.go
/Users/akutz/.go/1.8.1/src/runtime/defs_solaris_amd64.go
/Users/akutz/.go/1.8.1/src/runtime/defs_windows.go
/Users/akutz/.go/1.8.1/src/runtime/msan/msan.go
/Users/akutz/.go/1.8.1/src/runtime/race/output_test.go
/Users/akutz/.go/1.8.1/src/runtime/race/race.go
/Users/akutz/.go/1.8.1/src/runtime/race/testdata/cgo_test_main.go
/Users/akutz/.go/1.8.1/src/runtime/runtime-gdb_test.go
/Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/aprof.go
/Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/callback.go
/Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/cgo.go
/Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/deadlock.go
/Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/dll_windows.go
/Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/dropm.go
/Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/exec.go
/Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/pprof.go
/Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/raceprof.go
/Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/racesig.go
/Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/threadpanic.go
/Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/threadpprof.go
/Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/threadprof.go
/Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/traceback.go
/Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/tracebackctxt.go
/Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/windows/win.go
/Users/akutz/.go/1.8.1/src/syscall/types_darwin.go
/Users/akutz/.go/1.8.1/src/syscall/types_dragonfly.go
/Users/akutz/.go/1.8.1/src/syscall/types_freebsd.go
/Users/akutz/.go/1.8.1/src/syscall/types_linux.go
/Users/akutz/.go/1.8.1/src/syscall/types_netbsd.go
/Users/akutz/.go/1.8.1/src/syscall/types_openbsd.go
/Users/akutz/.go/1.8.1/src/syscall/types_solaris.go

@akutz
Copy link
Author

akutz commented May 22, 2017

Hi @bradfitz,

FWIW here's a diff between all of above "Hello" project's 1.8.1's Stdlib sources that import C with those from 1.7.4:

[0]akutz@pax:hello$ for pkg in $(GOARCH=arm /Users/akutz/.go/1.8.1/bin/go list -f '{{join .Deps "\n"}}' "hello"); do \
>   for f in $(find "/Users/akutz/.go/1.8.1/src/${pkg}" -name "*.go" -type f); do \
>     if grep 'import "C"' "$f" > /dev/null 2>&1; then \
>       s4="$(echo $f | sed 's/1.8.1/1.7.4/g')" && \
>       echo "diff $s4 $f" && \
>       diff "$s4" "$f"; \
>       echo; echo; \
>     fi; \
>   done; \
> done;
diff /Users/akutz/.go/1.7.4/src/os/user/getgrouplist_darwin.go /Users/akutz/.go/1.8.1/src/os/user/getgrouplist_darwin.go


diff /Users/akutz/.go/1.7.4/src/os/user/getgrouplist_unix.go /Users/akutz/.go/1.8.1/src/os/user/getgrouplist_unix.go


diff /Users/akutz/.go/1.7.4/src/os/user/listgroups_unix.go /Users/akutz/.go/1.8.1/src/os/user/listgroups_unix.go


diff /Users/akutz/.go/1.7.4/src/os/user/lookup_unix.go /Users/akutz/.go/1.8.1/src/os/user/lookup_unix.go


diff /Users/akutz/.go/1.7.4/src/runtime/cgo/cgo.go /Users/akutz/.go/1.8.1/src/runtime/cgo/cgo.go
23,25d22
< // we must explicitly link msvcrt, because runtime needs ntdll, and ntdll
< // exports some incompatible libc functions. See golang.org/issue/12030.
< #cgo windows LDFLAGS: -lmsvcrt -lm -mthreads


diff /Users/akutz/.go/1.7.4/src/runtime/defs1_linux.go /Users/akutz/.go/1.8.1/src/runtime/defs1_linux.go
36c36
< type SigaltstackT C.struct_sigaltstack
---
> type StackT C.stack_t


diff /Users/akutz/.go/1.7.4/src/runtime/defs2_linux.go /Users/akutz/.go/1.8.1/src/runtime/defs2_linux.go
142c142
< type SigaltstackT C.struct_sigaltstack
---
> type StackT C.stack_t


diff /Users/akutz/.go/1.7.4/src/runtime/defs3_linux.go /Users/akutz/.go/1.8.1/src/runtime/defs3_linux.go
38c38
< type SigaltstackT C.struct_sigaltstack
---
> type StackT C.stack_t


diff /Users/akutz/.go/1.7.4/src/runtime/defs_arm_linux.go /Users/akutz/.go/1.8.1/src/runtime/defs_arm_linux.go
118c118
< type SigaltstackT C.struct_sigaltstack
---
> type StackT C.stack_t


diff /Users/akutz/.go/1.7.4/src/runtime/defs_darwin.go /Users/akutz/.go/1.8.1/src/runtime/defs_darwin.go


diff /Users/akutz/.go/1.7.4/src/runtime/defs_dragonfly.go /Users/akutz/.go/1.8.1/src/runtime/defs_dragonfly.go
112d111
< type SigaltstackT C.struct_sigaltstack


diff /Users/akutz/.go/1.7.4/src/runtime/defs_freebsd.go /Users/akutz/.go/1.8.1/src/runtime/defs_freebsd.go
123d122
< type SigaltstackT C.struct_sigaltstack


diff /Users/akutz/.go/1.7.4/src/runtime/defs_linux.go /Users/akutz/.go/1.8.1/src/runtime/defs_linux.go


diff /Users/akutz/.go/1.7.4/src/runtime/defs_netbsd.go /Users/akutz/.go/1.8.1/src/runtime/defs_netbsd.go
112d111
< type SigaltstackT C.struct_sigaltstack


diff /Users/akutz/.go/1.7.4/src/runtime/defs_netbsd_386.go /Users/akutz/.go/1.8.1/src/runtime/defs_netbsd_386.go


diff /Users/akutz/.go/1.7.4/src/runtime/defs_netbsd_amd64.go /Users/akutz/.go/1.8.1/src/runtime/defs_netbsd_amd64.go


diff /Users/akutz/.go/1.7.4/src/runtime/defs_netbsd_arm.go /Users/akutz/.go/1.8.1/src/runtime/defs_netbsd_arm.go


diff /Users/akutz/.go/1.7.4/src/runtime/defs_openbsd.go /Users/akutz/.go/1.8.1/src/runtime/defs_openbsd.go
109d108
< type SigaltstackT C.struct_sigaltstack


diff /Users/akutz/.go/1.7.4/src/runtime/defs_solaris.go /Users/akutz/.go/1.8.1/src/runtime/defs_solaris.go
136d135
< type SigaltstackT C.struct_sigaltstack


diff /Users/akutz/.go/1.7.4/src/runtime/defs_solaris_amd64.go /Users/akutz/.go/1.8.1/src/runtime/defs_solaris_amd64.go


diff /Users/akutz/.go/1.7.4/src/runtime/defs_windows.go /Users/akutz/.go/1.8.1/src/runtime/defs_windows.go


diff /Users/akutz/.go/1.7.4/src/runtime/msan/msan.go /Users/akutz/.go/1.8.1/src/runtime/msan/msan.go


diff /Users/akutz/.go/1.7.4/src/runtime/race/output_test.go /Users/akutz/.go/1.8.1/src/runtime/race/output_test.go
9a10
> 	"internal/testenv"
14a16
> 	"runtime"
20a23,26
> 		if test.goos != "" && test.goos != runtime.GOOS {
> 			t.Logf("test %v runs only on %v, skipping: ", test.name, test.goos)
> 			continue
> 		}
44c50
< 		cmd := exec.Command("go", test.run, "-race", "-gcflags=-l", src)
---
> 		cmd := exec.Command(testenv.GoToolPath(t), test.run, "-race", "-gcflags=-l", src)
68a75
> 	goos   string
73c80
< 	{"simple", "run", "atexit_sleep_ms=0", `
---
> 	{"simple", "run", "", "atexit_sleep_ms=0", `
118c125
< 	{"exitcode", "run", "atexit_sleep_ms=0 exitcode=13", `
---
> 	{"exitcode", "run", "", "atexit_sleep_ms=0 exitcode=13", `
132c139
< 	{"strip_path_prefix", "run", "atexit_sleep_ms=0 strip_path_prefix=/main.", `
---
> 	{"strip_path_prefix", "run", "", "atexit_sleep_ms=0 strip_path_prefix=/main.", `
148c155
< 	{"halt_on_error", "run", "atexit_sleep_ms=0 halt_on_error=1", `
---
> 	{"halt_on_error", "run", "", "atexit_sleep_ms=0 halt_on_error=1", `
165c172
< 	{"test_fails_on_race", "test", "atexit_sleep_ms=0", `
---
> 	{"test_fails_on_race", "test", "", "atexit_sleep_ms=0", `
180,181c187,188
< PASS
< Found 1 data race\(s\)
---
> --- FAIL: TestFail \(0...s\)
> .*testing.go:.*: race detected during execution of test
184c191
< 	{"slicebytetostring_pc", "run", "atexit_sleep_ms=0", `
---
> 	{"slicebytetostring_pc", "run", "", "atexit_sleep_ms=0", `
199a207,259
> 
> 	// Test for http://golang.org/issue/17190
> 	{"external_cgo_thread", "run", "linux", "atexit_sleep_ms=0", `
> package main
> 
> /*
> #include <pthread.h>
> typedef struct cb {
>         int foo;
> } cb;
> extern void goCallback();
> static inline void *threadFunc(void *p) {
> 	goCallback();
> 	return 0;
> }
> static inline void startThread(cb* c) {
> 	pthread_t th;
> 	pthread_create(&th, 0, threadFunc, 0);
> }
> */
> import "C"
> 
> import "time"
> 
> var racy int
> 
> //export goCallback
> func goCallback() {
> 	racy++
> }
> 
> func main() {
> 	var c C.cb
> 	C.startThread(&c)
> 	time.Sleep(time.Second)
> 	racy++
> }
> `, `==================
> WARNING: DATA RACE
> Read at 0x[0-9,a-f]+ by main goroutine:
>   main\.main\(\)
>       .*/main\.go:34 \+0x[0-9,a-f]+
> 
> Previous write at 0x[0-9,a-f]+ by goroutine [0-9]:
>   main\.goCallback\(\)
>       .*/main\.go:27 \+0x[0-9,a-f]+
>   main._cgoexpwrap_[0-9a-z]+_goCallback\(\)
>       .*/_cgo_gotypes\.go:[0-9]+ \+0x[0-9,a-f]+
> 
> Goroutine [0-9] \(running\) created at:
>   runtime\.newextram\(\)
>       .*/runtime/proc.go:[0-9]+ \+0x[0-9,a-f]+
> ==================`},


diff /Users/akutz/.go/1.7.4/src/runtime/race/race.go /Users/akutz/.go/1.8.1/src/runtime/race/race.go


diff /Users/akutz/.go/1.7.4/src/runtime/race/testdata/cgo_test_main.go /Users/akutz/.go/1.8.1/src/runtime/race/testdata/cgo_test_main.go


diff /Users/akutz/.go/1.7.4/src/runtime/runtime-gdb_test.go /Users/akutz/.go/1.8.1/src/runtime/runtime-gdb_test.go
9a10
> 	"go/build"
17a19
> 	"strings"
25a28,30
> 	if runtime.GOOS == "linux" && runtime.GOARCH == "ppc64" {
> 		t.Skip("skipping gdb tests on linux/ppc64; see golang.org/issue/17366")
> 	}
66d70
< package main
67a72
> var gslice []string
74c79,81
< 	fmt.Println("hi") // line 10
---
> 	slicevar := make([]string, 0, 16)
> 	slicevar = append(slicevar, mapvar["abc"])
> 	fmt.Println("hi") // line 12
75a83
> 	gslice = slicevar
79a88,103
> 	testGdbPython(t, false)
> }
> 
> func TestGdbPythonCgo(t *testing.T) {
> 	testGdbPython(t, true)
> }
> 
> func testGdbPython(t *testing.T, cgo bool) {
> 	if runtime.GOARCH == "mips64" {
> 		testenv.SkipFlaky(t, 18173)
> 	}
> 	if cgo && !build.Default.CgoEnabled {
> 		t.Skip("skipping because cgo is not enabled")
> 	}
> 
> 	t.Parallel()
89a114,120
> 	var buf bytes.Buffer
> 	buf.WriteString("package main\n")
> 	if cgo {
> 		buf.WriteString(`import "C"` + "\n")
> 	}
> 	buf.WriteString(helloSource)
> 
91c122
< 	err = ioutil.WriteFile(src, []byte(helloSource), 0644)
---
> 	err = ioutil.WriteFile(src, buf.Bytes(), 0644)
96c127
< 	cmd := exec.Command("go", "build", "-o", "a.exe")
---
> 	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", "a.exe")
108c139
< 		"-ex", "br main.go:10",
---
> 		"-ex", "br fmt.Println",
112a144
> 		"-ex", "up", // up from fmt.Println to main
118,129c150,158
< 		"-ex", "echo END\n"}
< 
< 	// without framepointer, gdb cannot backtrace our non-standard
< 	// stack frames on RISC architectures.
< 	canBackTrace := false
< 	switch runtime.GOARCH {
< 	case "amd64", "386", "ppc64", "ppc64le", "arm", "arm64", "mips64", "mips64le", "s390x":
< 		canBackTrace = true
< 		args = append(args,
< 			"-ex", "echo BEGIN goroutine 2 bt\n",
< 			"-ex", "goroutine 2 bt",
< 			"-ex", "echo END\n")
---
> 		"-ex", "echo END\n",
> 		"-ex", "echo BEGIN info locals\n",
> 		"-ex", "info locals",
> 		"-ex", "echo END\n",
> 		"-ex", "down", // back to fmt.Println (goroutine 2 below only works at bottom of stack.  TODO: fix that)
> 		"-ex", "echo BEGIN goroutine 2 bt\n",
> 		"-ex", "goroutine 2 bt",
> 		"-ex", "echo END\n",
> 		filepath.Join(dir, "a.exe"),
131,132d159
< 
< 	args = append(args, filepath.Join(dir, "a.exe"))
140c167
< 		cmd := exec.Command("go", "env", "GOROOT")
---
> 		cmd := exec.Command(testenv.GoToolPath(t), "env", "GOROOT")
174a202,210
> 	// Issue 16338: ssa decompose phase can split a structure into
> 	// a collection of scalar vars holding the fields. In such cases
> 	// the DWARF variable location expression should be of the
> 	// form "var.field" and not just "field".
> 	infoLocalsRe := regexp.MustCompile(`^slicevar.len = `)
> 	if bl := blocks["info locals"]; !infoLocalsRe.MatchString(bl) {
> 		t.Fatalf("info locals failed: %s", bl)
> 	}
> 
176c212
< 	if bl := blocks["goroutine 2 bt"]; canBackTrace && !btGoroutineRe.MatchString(bl) {
---
> 	if bl := blocks["goroutine 2 bt"]; !btGoroutineRe.MatchString(bl) {
178,179d213
< 	} else if !canBackTrace {
< 		t.Logf("gdb cannot backtrace for GOARCH=%s, skipped goroutine backtrace test", runtime.GOARCH)
211,213d244
< 	checkGdbEnvironment(t)
< 	checkGdbVersion(t)
< 
216a248,254
> 	if runtime.GOARCH == "mips64" {
> 		testenv.SkipFlaky(t, 18173)
> 	}
> 
> 	t.Parallel()
> 	checkGdbEnvironment(t)
> 	checkGdbVersion(t)
230c268
< 	cmd := exec.Command("go", "build", "-o", "a.exe")
---
> 	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", "a.exe")
265a304,376
> 
> const autotmpTypeSource = `
> package main
> 
> type astruct struct {
> 	a, b int
> }
> 
> func main() {
> 	var iface interface{} = map[string]astruct{}
> 	var iface2 interface{} = []astruct{}
> 	println(iface, iface2)
> }
> `
> 
> // TestGdbAutotmpTypes ensures that types of autotmp variables appear in .debug_info
> // See bug #17830.
> func TestGdbAutotmpTypes(t *testing.T) {
> 	if runtime.GOARCH == "mips64" {
> 		testenv.SkipFlaky(t, 18173)
> 	}
> 
> 	t.Parallel()
> 	checkGdbEnvironment(t)
> 	checkGdbVersion(t)
> 
> 	dir, err := ioutil.TempDir("", "go-build")
> 	if err != nil {
> 		t.Fatalf("failed to create temp directory: %v", err)
> 	}
> 	defer os.RemoveAll(dir)
> 
> 	// Build the source code.
> 	src := filepath.Join(dir, "main.go")
> 	err = ioutil.WriteFile(src, []byte(autotmpTypeSource), 0644)
> 	if err != nil {
> 		t.Fatalf("failed to create file: %v", err)
> 	}
> 	cmd := exec.Command(testenv.GoToolPath(t), "build", "-gcflags=-N -l", "-o", "a.exe")
> 	cmd.Dir = dir
> 	out, err := testEnv(cmd).CombinedOutput()
> 	if err != nil {
> 		t.Fatalf("building source %v\n%s", err, out)
> 	}
> 
> 	// Execute gdb commands.
> 	args := []string{"-nx", "-batch",
> 		"-ex", "set startup-with-shell off",
> 		"-ex", "break main.main",
> 		"-ex", "run",
> 		"-ex", "step",
> 		"-ex", "info types astruct",
> 		filepath.Join(dir, "a.exe"),
> 	}
> 	got, _ := exec.Command("gdb", args...).CombinedOutput()
> 
> 	sgot := string(got)
> 
> 	// Check that the backtrace matches the source code.
> 	types := []string{
> 		"struct []main.astruct;",
> 		"struct bucket<string,main.astruct>;",
> 		"struct hash<string,main.astruct>;",
> 		"struct main.astruct;",
> 		"typedef struct hash<string,main.astruct> * map[string]main.astruct;",
> 	}
> 	for _, name := range types {
> 		if !strings.Contains(sgot, name) {
> 			t.Errorf("could not find %s in 'info typrs astruct' output", name)
> 			t.Fatalf("gdb output:\n%v", sgot)
> 		}
> 	}
> }


diff /Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/aprof.go /Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/aprof.go


diff /Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/callback.go /Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/callback.go


diff /Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/cgo.go /Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/cgo.go


diff /Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/deadlock.go /Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/deadlock.go


diff /Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/dll_windows.go /Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/dll_windows.go


diff /Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/dropm.go /Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/dropm.go


diff /Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/exec.go /Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/exec.go


diff /Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/pprof.go /Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/pprof.go
1c1
< // Copyright 2016 The Go Authors.  All rights reserved.
---
> // Copyright 2016 The Go Authors. All rights reserved.


diff /Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/raceprof.go /Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/raceprof.go
diff: /Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/raceprof.go: No such file or directory


diff /Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/racesig.go /Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/racesig.go
diff: /Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/racesig.go: No such file or directory


diff /Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/threadpanic.go /Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/threadpanic.go


diff /Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/threadpprof.go /Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/threadpprof.go
1c1
< // Copyright 2016 The Go Authors.  All rights reserved.
---
> // Copyright 2016 The Go Authors. All rights reserved.
42,52d41
< static void *pprofThread(void* p) {
< 	time_t start;
< 
< 	(void)p;
< 	start = time(NULL);
< 	while (__sync_add_and_fetch(&cpuHogThreadCount, 0) < 2 && time(NULL) - start < 2) {
< 		cpuHogThread();
< 	}
< }
< 
< 
66a56,67
> 
> static void* cpuHogDriver(void* arg __attribute__ ((unused))) {
> 	while (1) {
> 		cpuHogThread();
> 	}
> 	return 0;
> }
> 
> void runCPUHogThread(void) {
> 	pthread_t tid;
> 	pthread_create(&tid, 0, cpuHogDriver, 0);
> }
81a83
> 	register("CgoPprofThreadNoTraceback", CgoPprofThreadNoTraceback)
85a88,93
> 	pprofThread()
> }
> 
> func CgoPprofThreadNoTraceback() {
> 	pprofThread()
> }
86a95
> func pprofThread() {
97a107,108
> 	C.runCPUHogThread()
> 


diff /Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/threadprof.go /Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/threadprof.go
4a5,7
> // We only build this file with the tag "threadprof", since it starts
> // a thread running a busy loop at constructor time.
> 
5a9
> // +build threadprof
23a28
> 
87,88c92,93
< 		fmt.Println("C signal did not crash as expected\n")
< 		fmt.Printf("%s\n", out)
---
> 		fmt.Println("C signal did not crash as expected")
> 		fmt.Printf("\n%s\n", out)


diff /Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/traceback.go /Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/traceback.go
18c18
< static int f3() {
---
> static int f3(void) {
23c23
< static int f2() {
---
> static int f2(void) {
27c27
< static int f1() {
---
> static int f1(void) {


diff /Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/tracebackctxt.go /Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/tracebackctxt.go


diff /Users/akutz/.go/1.7.4/src/runtime/testdata/testprogcgo/windows/win.go /Users/akutz/.go/1.8.1/src/runtime/testdata/testprogcgo/windows/win.go


diff /Users/akutz/.go/1.7.4/src/syscall/types_darwin.go /Users/akutz/.go/1.8.1/src/syscall/types_darwin.go


diff /Users/akutz/.go/1.7.4/src/syscall/types_dragonfly.go /Users/akutz/.go/1.8.1/src/syscall/types_dragonfly.go


diff /Users/akutz/.go/1.7.4/src/syscall/types_freebsd.go /Users/akutz/.go/1.8.1/src/syscall/types_freebsd.go


diff /Users/akutz/.go/1.7.4/src/syscall/types_linux.go /Users/akutz/.go/1.8.1/src/syscall/types_linux.go
115c115
< #ifdef __ARM_EABI__
---
> #if defined(__ARM_EABI__) || (defined(__mips__) && _MIPS_SIM == _ABIO32)


diff /Users/akutz/.go/1.7.4/src/syscall/types_netbsd.go /Users/akutz/.go/1.8.1/src/syscall/types_netbsd.go


diff /Users/akutz/.go/1.7.4/src/syscall/types_openbsd.go /Users/akutz/.go/1.8.1/src/syscall/types_openbsd.go


diff /Users/akutz/.go/1.7.4/src/syscall/types_solaris.go /Users/akutz/.go/1.8.1/src/syscall/types_solaris.go

@ianlancetaylor
Copy link
Contributor

I believe this changed in https://golang.org/cl/28971, which forces external linking for darwin-arm and darwin-arm64. Before that change, the linker forced external linking for cgo code on those platforms. After that change, the linker forced external linking for all code on those platforms.

@crawshaw Do you remember anything about this?

@bradfitz
Copy link
Contributor

/cc @eliasnaur

@bradfitz bradfitz modified the milestones: Go1.10, Go1.9Maybe Jul 20, 2017
@bradfitz
Copy link
Contributor

I guess we don't have a Mobile label. @eliasnaur, do you want one?

@eliasnaur
Copy link
Contributor

SGTM.

@bradfitz bradfitz added the mobile Android, iOS, and x/mobile label Jul 20, 2017
@rsc
Copy link
Contributor

rsc commented Dec 1, 2017

I think it is OK that we force external linking here. Those systems are always going to be fussy about the binaries and using the external linker means that we're more likely to get a working binary out. When cross-compiling, this means you have to set $CC during your go build command, or else (as of Go 1.10) set CC_FOR_darwin_arm and CC_FOR_darwin_arm64 during make.bash (see go doc cgo on master). See src/iostest.bash in the main repo for an example of cross-compiling for darwin_arm and darwin_arm64 from macOS. That is working for me, at least for compilation. (I can't run the results because I don't have the rest of the iOS dev env set up.)

@rsc rsc closed this as completed Dec 1, 2017
@golang golang locked and limited conversation to collaborators Dec 1, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge help wanted mobile Android, iOS, and x/mobile NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Darwin
Projects
None yet
Development

No branches or pull requests

6 participants