Skip to content

darwin/arm64 binary says it is running under Rosetta 2 on macOS M1 machine #44733

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
mx-psi opened this issue Mar 2, 2021 · 2 comments
Closed
Labels
arch-arm64 FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Darwin

Comments

@mx-psi
Copy link

mx-psi commented Mar 2, 2021

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

$ go version
go version go1.16 darwin/amd64

Does this issue reproduce with the latest release?

Yes, Go 1.16 is the latest release.

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

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/[name]/Library/Caches/go-build"
GOENV="/Users/[name]/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/[name]/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/[name]/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/Cellar/go/1.16/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.16/libexec/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.16"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/[name]/dd/gotest/darwin/go.mod"
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 x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/6d/hrpbskwn3nv8qnm51fdpmh5c0000gn/T/go-build1276543076=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

Consider the following program, saved on main.go:

package main

import (
	"fmt"
	"golang.org/x/sys/unix"
)

func processIsTranslated() (bool, error) {
	// https://developer.apple.com/documentation/apple_silicon/about_the_rosetta_translation_environment#3616845
	_, err := unix.Sysctl("sysctl.proc_translated")

	if err == nil {
		return true, nil
	} else if err.(unix.Errno) == unix.ENOENT {
		return false, nil
	}

	return false, err
}

func main() {
	if isTranslated, err := processIsTranslated(); err != nil {
		panic(err)
	} else if isTranslated {
		fmt.Println("Running on Rosetta 2")
	} else {
		fmt.Println("Running natively")
	}
}

As per Apple's documentation, if I am translating the code correctly to Go, this should detect whether a binary is running natively or it is being translated under Rosetta.

Build the program both for amd64 and arm64 on macOS:

GOOS=darwin GOARCH=amd64 go build -o main_darwin_amd64 main.go
GOOS=darwin GOARCH=arm64 go build -o main_darwin_arm64 main.go

What did you expect to see?

The amd64 binary should report it is running natively on a macOS with amd64 architecture and it should report it is running under Rosetta 2 on a macOS with arm64 architecture.

The arm64 binary should not be runnable on a macOS with amd64 architecture and it should report it is running natively on a macOS with arm64 architecture.

What did you see instead?

When running on a macOS with an amd64 architecture I see the following

$ uname -a
Darwin [name].local 19.6.0 Darwin Kernel Version 19.6.0: Tue Jan 12 22:13:05 PST 2021; root:xnu-6153.141.16~1/RELEASE_X86_64 x86_64 i386 MacBookPro15,2 Darwin
$ file ./main_darwin_amd64
./main_darwin_amd64: Mach-O 64-bit executable x86_64
$ ./main_darwin_amd64
Running natively
$ file ./main_darwin_arm64
./main_darwin_arm64: Mach-O 64-bit executable arm64
$ ./main_darwin_arm64
-bash: ./main_darwin_arm64: Bad CPU type in executable

When running on a macOS with an arm64 architecture (with a macOS M1 chip) I see the following

$ uname -a
Darwin [name].local 20.1.0 Darwin Kernel Version 20.1.0: Sat Oct 31 00:07:18 PDT 2020; root:xnu-7195.50.7~2/RELEASE_ARM64_T8020 arm64
$ file ./main_darwin_amd64
./main_darwin_amd64: Mach-O 64-bit executable x86_64
$ ./main_darwin_amd64
Running on Rosetta 2
$ file ./main_darwin_arm64
./main_darwin_arm64: Mach-O 64-bit executable arm64
$ ./main_darwin_arm64
Running on Rosetta 2  # ?!?

I would expect this last line to say Running natively since it is an arm64 executable on an arm64 macOS.

@seankhliao seankhliao added arch-arm64 NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-Darwin labels Mar 2, 2021
@mx-psi
Copy link
Author

mx-psi commented Mar 2, 2021

Compare with the following C++ program which does output the results I would expect: the arm64 version reports "Running natively" on the Mac with the M1 chip.

#include <iostream>
#include <sys/sysctl.h>

int processIsTranslated() {
  int ret = 0;
  size_t size = sizeof(ret);
  if (sysctlbyname("sysctl.proc_translated", &ret, &size, nullptr, 0) == -1) {
    if (errno == ENOENT)
      return 0;
    return -1;
  }
  return ret;
}

int main() {
  int res = processIsTranslated();
  if (res == 0) {
    std::cout << "Process is running natively" << std::endl;
  } else if (res == 1) {
    std::cout << "Process is running under Rosetta" << std::endl;
  } else {
    std::cout << "Unexpected error code: " << res << std::endl;
  }
}

Notice the return ret, however this doesn't work with unix.Sysctl since it always returns a string that does not correspond to the numbers here

@mx-psi
Copy link
Author

mx-psi commented Mar 2, 2021

Closing as it was an issue in my code. The correct implementation of the function in Go is:

func processIsTranslated() (bool, error) {
	// https://developer.apple.com/documentation/apple_silicon/about_the_rosetta_translation_environment#3616845
	ret, err := unix.SysctlUint32("sysctl.proc_translated")

	if err == nil {
		return ret == 1, nil
	} else if err.(unix.Errno) == unix.ENOENT {
		return false, nil
	}

	return false, err
}

@mx-psi mx-psi closed this as completed Mar 2, 2021
@golang golang locked and limited conversation to collaborators Mar 2, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
arch-arm64 FrozenDueToAge 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

3 participants