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: fail nicely on start-up on softfloat mips systems if binary built with GOMIPS=hardfloat (the default) #23614

Closed
dtodor opened this issue Jan 30, 2018 · 13 comments

Comments

Projects
None yet
9 participants
@dtodor
Copy link

commented Jan 30, 2018

We have a problem running a simple Go program on a MIPS target with the following FPU configuration:

CONFIG_MIPS_FPU_EMULATOR=n
CONFIG_CPU_R4K_FPU=y

On the same target with the CONFIG_MIPS_FPU_EMULATOR enabled, the program runs as expected. My understanding is that the latest release Go compiler only supports hard-float on MIPS, with soft-float implemented in go1.10RC1. Is this correct?

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

The following Go versions have been tested:
go1.8.3
go1.9.3
go1.10RC1

Does this issue reproduce with the latest release?

Yes.

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

The program is built on OS X:

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/***/Development/go"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/49/p0474r8s3330n15jxw8n65fw0000gp/T/go-build208700080=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"

The target is MIPS32 big endian (GRX550).

What did you do?

Build and run the following sample program: https://play.golang.org/p/XHRe6Hv6Jeb

Build instructions:

GOOS=linux GOARCH=mips go build -a -o info

What did you expect to see?

The output of the program, e.g.:

./info
GOOS: linux
GOARCH: mips
Compiler: gc
Version: go1.8.3
No. of CPU: 2

What did you see instead?

The program immediately terminates:

./info
Segmentation fault
@vstefanovic

This comment has been minimized.

Copy link
Member

commented Jan 30, 2018

Looks like you're missing GOMIPS=softfloat. (Default is hardfloat.)

@bradfitz

This comment has been minimized.

Copy link
Member

commented Jan 30, 2018

This is documented at https://tip.golang.org/doc/go1.10#ports and https://tip.golang.org/cmd/go/#hdr-Environment_variables but I don't see it documented at

https://tip.golang.org/doc/install/source

It should be documented there if GOARM and GO386 are.

(I see it's also at https://tip.golang.org/doc/asm#mips but that's only relevant to a small audience)

@gopherbot

This comment has been minimized.

Copy link

commented Jan 30, 2018

Change https://golang.org/cl/90815 mentions this issue: doc: add GOMIPS to source installation docs

@randall77

This comment has been minimized.

Copy link
Contributor

commented Jan 30, 2018

It would also be nice if the binary startup detected the problem and reported a nicer error message than "segmentation fault".
We do this on 386 to detect non-MMX chips and fail nicely.

@cherrymui

This comment has been minimized.

Copy link
Contributor

commented Jan 30, 2018

I'm a little surprised that it is segmentation fault instead of illegal instruction.

Either way, I agree that it would be nice to print a nicer error message. On ARM, we do this by querying the HWCAP bits at startup, and see if the GOARM value is compatible with HWCAP. On MIPS, it seems no HWCAP bit for whether it has FPU. Is there something we can query without trapping?

@bradfitz bradfitz changed the title MIPS FPU Configuration runtime: fail nicely on start-up on softfloat mips systems if binary built with GOMIPS=hardfloat (the default) Jan 30, 2018

@bradfitz bradfitz added this to the Go1.11 milestone Jan 30, 2018

@bradfitz bradfitz reopened this Jan 30, 2018

@dtodor

This comment has been minimized.

Copy link
Author

commented Jan 30, 2018

I'm pretty sure we tested the GOMIPS=softfloat with the go1.10RC1 compiler without much success. We found the relevant information about the soft-float support on MIPS in this issue: #18162.

@minux

This comment has been minimized.

Copy link
Member

commented Jan 30, 2018

@crvv

This comment has been minimized.

Copy link
Contributor

commented Jan 31, 2018

I can't reproduce this issue.
If I build it with GOMIPS=hardfloat, it will fail with Illegal instruction, not Segmentation fault.

Linux LEDE 4.4.89 #0 Sat Sep 30 18:37:33 2017 mips GNU/Linux
Atheros AR9344 rev 2
MIPS 74Kc V4.12
@dtodor

This comment has been minimized.

Copy link
Author

commented Jan 31, 2018

OK, I can verify that GOMIPS=softfloat doesn't work on the target:

GOOS=linux GOARCH=mips GOMIPS=softfloat go1.10rc1 build -a

The result of executing the binary is again a segmentation fault. Our partners have built a kernel with CONFIG_MIPS_FPU_EMULATOR=y, which results in binaries built with the 1.9.3 Go compiler without specifying GOMIPS to work without a problem. My guess is that there is a problem with the softfloat MIPS implementation in Go 1.10RC1.

@dtodor

This comment has been minimized.

Copy link
Author

commented Jan 31, 2018

A follow-up: we have compiled the sample project with a custom build of GCCGO. The binary still uses hard-float, but now we get the "correct" error message: Illegal instruction instead of Segmentation fault.

@vstefanovic

This comment has been minimized.

Copy link
Member

commented Jan 31, 2018

I also cannot reproduce this - GOMIPS=softfloat is working, GOMIPS=hardfloat brings illegal instruction.
@dtodor, do you have any other info; can you catch the segfault with gdb?

@dtodor

This comment has been minimized.

Copy link
Author

commented Feb 1, 2018

We've attached a gdb to the target and run the program. Unfortunately, the debugger outputs:
not in executable format: File format not recognized

This probably means that the Go compiler cannot produce a valid executable for the target. This would explain the Segmentation fault. Using the custom built GCCGO compiler, the debugger runs and catches the Illegal instruction. Maybe the current firmware on the target is somehow "special". The weird thing is that enabling CONFIG_MIPS_FPU_EMULATOR in the kernel solves the problem. This has been verified by our partners, who provide us with the firmware.

Unfortunately we have to flash the new firmware onto the device and thus cannot do any further testing of this issue.

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Jul 9, 2018

As far as I can tell, only @dtodor was able to recreate the problem, and that is no longer possible. So, closing. Please comment if you disagree.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.