Bug 230731 - lang/go: crash with SIGILL using 586-class CPU
Summary: lang/go: crash with SIGILL using 586-class CPU
Status: Closed FIXED
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: i386 Any
: --- Affects Some People
Assignee: Dmitri Goutnik
Depends on: 230733
  Show dependency treegraph
Reported: 2018-08-18 12:25 UTC by Eugene Grosbein
Modified: 2020-04-11 23:16 UTC (History)
4 users (show)

See Also:
bugzilla: maintainer-feedback?


Note You need to log in before you can comment on or make changes to this bug.
Description Eugene Grosbein freebsd_committer 2018-08-18 12:25:58 UTC
I'm creating new port that USES=go. It already runs just fine using amd64 system. Now I need to test it using FreeBSD 11/i386. I've used "pkg install go" to install go-1.10.3,1 to my i386 system that has this CPU:

CPU: Geode(TM) Integrated Processor by AMD PCS (499.91-MHz 586-class CPU)
  Origin="AuthenticAMD"  Id=0x5a2  Family=0x5  Model=0xa  Stepping=2
  AMD Features=0xc0400000<MMX+,3DNow!+,3DNow!>

When "make" runs "go" to build the software, "go" crashes with SIGILL (illegal instruction). Here is part of kdump output:

 55336 go       CALL  thr_self(0x28a14000)
 55336 go       RET   thr_self 0
 55336 go       CALL  mmap(0xbbbfe000,0x1000,0<PROT_NONE>,0x1000<MAP_ANON>,0xffffffff,0,0)
 55336 go       RET   mmap -1145053184/0xbbbfe000
 55336 go       CALL  rtprio_thread(0,0x18835,0xbfbfd840)
 55336 go       RET   rtprio_thread 0
 55336 go       CALL  sysarch(0xa,0xbfbfd840)
 55336 go       RET   sysarch 0
 55336 go       CALL  sigaction(SIG 32,0xbfbfd820,0)
 55336 go       RET   sigaction 0
 55336 go       CALL  sigprocmask(SIG_UNBLOCK,0xbfbfd828,0)
 55336 go       RET   sigprocmask 0
 55336 go       CALL  _umtx_op(0xbfbfd814,UMTX_OP_WAKE,0x1,0,0)
 55336 go       RET   _umtx_op 0
 55336 go       CALL  mprotect(0,0,0<PROT_NONE>)
 55336 go       RET   mprotect 0
 55336 go       CALL  getpid
 55336 go       RET   getpid 55336/0xd828
 55336 go       CALL  getpid
 55336 go       RET   getpid 55336/0xd828
 55336 go       CALL  sigprocmask(SIG_BLOCK,0x28646a1c,0x28a140a0)
 55336 go       RET   sigprocmask 0
 55336 go       CALL  sigprocmask(SIG_SETMASK,0x28a140a0,0)
 55336 go       RET   sigprocmask 0
 55336 go       CALL  getcontext(0xbfbfd550)
 55336 go       RET   getcontext 0
 55336 go       PSIG  SIGILL SIG_DFL code=ILL_PRVOPC
 55336 go       NAMI  "go.core"
 55323 make     RET   wait4 55336/0xd828

This system is pretty busy and runs lots of software just fine: NFS Server, Unbound, Quagga, Samba, Transmission, Mpd5, hostapd, ISC DHCPD, ntpd, lpd, racoon, Midnight Commander, all rock stable excluding this go package.
Comment 1 Dmitri Goutnik freebsd_committer 2018-08-18 13:10:44 UTC
Looks like lang/go will have to be rebuild from ports (with GO387=on) to support this CPU.

The binary package's go is built with GO386=sse2 which requires Pentium 4 or later.
Comment 2 Eugene Grosbein freebsd_committer 2018-08-18 13:19:27 UTC
(In reply to Dmitri Goutnik from comment #1)

Thank you for clarification.

It would be nice to have distinct flavour of the port supporting all systems in addition to default flavour targeted for performance and modern CPUs.
Comment 3 Dmitri Goutnik freebsd_committer 2018-08-18 14:10:25 UTC

poudriere testport OK on 112a, 104i
Comment 4 Eugene Grosbein freebsd_committer 2018-08-18 15:34:54 UTC
The package go14 (lang/go14) has exactly same problem - it crashes with SIGILL trying to build lang/go.
Comment 5 Dmitri Goutnik freebsd_committer 2018-08-18 15:55:22 UTC
Does lang/go14 build if you add GO386=387 to the make.bash environment? For some reason, lang/go14 lacks port knob for this.
Comment 6 Eugene Grosbein freebsd_committer 2018-08-18 16:01:16 UTC
(In reply to Dmitri Goutnik from comment #5)

I've successfully built lang/go14 adding GO386=387 to port's Makefile "do-build:" section and it no more crashes while building latest lang/go.
Comment 7 Dmitri Goutnik freebsd_committer 2018-08-18 16:03:46 UTC
(In reply to Eugene Grosbein from comment #6)

I think we should probably flavorize lang/go14 too then, will post phab review shortly.
Comment 8 Eugene Grosbein freebsd_committer 2018-08-18 16:14:24 UTC
(In reply to Dmitri Goutnik from comment #7)

It would be simplier to set GO386=387 unconditionally for go14 as it is used for bootstrapping lang/go only. We have no other consumers of go14 in the ports tree.
Comment 9 Dmitri Goutnik freebsd_committer 2018-08-18 16:48:17 UTC
Makes sense, https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=230733
Comment 10 Dmitri Goutnik freebsd_committer 2018-08-20 13:37:39 UTC
After discussion with mat@, port option seems like a best way to go. Flavors won't really work here because all existing Go ports depend on lang/go, not on lang/go@nosse2 so @nosse2 package will be only useful for playing with Go code in GOPATH, not for building ports.
Comment 11 Eugene Grosbein freebsd_committer 2018-08-20 14:48:23 UTC
(In reply to Dmitri Goutnik from comment #10)

mat is wrong and missed the point. Any golang port can be built with SSE2-disabled golang compiler providing same binaries. An example is lang/go itself being built by binaries provided by go14 compiled to not use SSE2.
Comment 12 Dmitri Goutnik freebsd_committer 2018-08-20 15:13:27 UTC
My understanding is that the issue with -nosse2 flavor is that all Go stuff the ports tree has a build dependency on lang/go and not on lang/go@${GO_FLAVOR}. So while manual port building will work as long as go  executable is found, it will not work if someone who's not aware of -nosse2 package will try to build, say, devel/awless - wrong (-default) go package will be installed through BUILD_DEPENDS and build will fail.
Comment 13 Dmitri Goutnik freebsd_committer 2018-08-20 15:22:25 UTC
So making flavorized version work in 100% of cases will require either flavorization of all Go build dependencies (probably out of the question) or getting all port users aware that they need to manually install -nosse2 flavor first.
Comment 14 Eugene Grosbein freebsd_committer 2018-08-20 15:24:55 UTC
(In reply to Dmitri Goutnik from comment #12)

This is still much better than not having go-nosse2 in official repository because it is large software and needs about 500MB of free RAM to build and takes lot of time for old CPU. The possibility to just install go-nosse2 package is great relief.

When and if some port founds to be useful for such old CPU, it could be built manually if it's small or flavourized too if it's large. The port in question I'm trying to create will benefit from go-nosse2 and will be flavourized too.
Comment 15 Eugene Grosbein freebsd_committer 2018-08-20 15:26:22 UTC
(In reply to Dmitri Goutnik from comment #13)

I do not understand why do you talking about "all go ports". Not every such port is useful for embedded applications using similar fanless special CPU.
Comment 16 Jan Bramkamp 2018-08-20 16:07:55 UTC
IIRC the Go compiler generates SSE2 code by default. This GitHub issue has documents how to generate code without SSE2 https://github.com/golang/go/issues/11631. I don't know if this is still supported because there are very few such systems left and even fewer of them are exposed to code written in Go.
Comment 17 Eugene Grosbein freebsd_committer 2018-08-20 16:15:03 UTC
(In reply to Jan Bramkamp from comment #16)

It is still supported and works for me.
Comment 18 Dmitri Goutnik freebsd_committer 2018-08-20 16:27:29 UTC
(In reply to Eugene Grosbein from comment #15)

Maybe the easiest solution would be to always set GO386=387 for i386 lang/go builds. Most current i386 CPUs are in low power/embedded devices and compatibility seems to be more important than performance there.
Comment 19 Eugene Grosbein freebsd_committer 2018-08-20 16:40:11 UTC
(In reply to Dmitri Goutnik from comment #18)

You forgot virtualization and 32-bit guests running on SSE2-enabled hosts.
Comment 20 Dmitri Goutnik freebsd_committer 2018-08-20 16:48:35 UTC
(In reply to Eugene Grosbein from comment #19)

Right. Not always then, just set GO387=on to be the default on i386. Then lang/go and binary packages will at least be runnable.
Comment 21 Eugene Grosbein freebsd_committer 2018-08-20 17:06:37 UTC
(In reply to Dmitri Goutnik from comment #20)

Well, better than nothing.
Comment 22 Dmitri Goutnik freebsd_committer 2020-04-11 23:16:17 UTC
I believe this was fixed by ports r478134.