semantic: 0.961 vnc: 0.955 other: 0.944 device: 0.942 graphic: 0.934 KVM: 0.899 assembly: 0.892 instruction: 0.888 mistranslation: 0.869 socket: 0.851 network: 0.851 boot: 0.835 golang binaries fail to start under linux-user With current master golang binaries fail when run under linux-user, for example: [will@localhost qemu]$ ./arm-linux-user/qemu-arm glide runtime: failed to create new OS thread (have 2 already; errno=22) fatal error: newosproc runtime stack: runtime.throw(0x45f879, 0x9) /usr/lib/golang/src/runtime/panic.go:566 +0x78 runtime.newosproc(0x1092c000, 0x1093bfe0) /usr/lib/golang/src/runtime/os_linux.go:160 +0x1b0 runtime.newm(0x4ae1e8, 0x0) /usr/lib/golang/src/runtime/proc.go:1572 +0x12c runtime.main.func1() /usr/lib/golang/src/runtime/proc.go:126 +0x24 runtime.systemstack(0x5ef900) /usr/lib/golang/src/runtime/asm_arm.s:247 +0x80 runtime.mstart() /usr/lib/golang/src/runtime/proc.go:1079 goroutine 1 [running]: runtime.systemstack_switch() /usr/lib/golang/src/runtime/asm_arm.s:192 +0x4 fp=0x109287ac sp=0x109287a8 runtime.main() /usr/lib/golang/src/runtime/proc.go:127 +0x5c fp=0x109287d4 sp=0x109287ac runtime.goexit() /usr/lib/golang/src/runtime/asm_arm.s:998 +0x4 fp=0x109287d4 sp=0x109287d4 The reason for this is that the golang runtime does not pass the CLONE_SYSVMEM flag to clone so the clone flags checks fail: https://github.com/golang/go/blob/master/src/runtime/os_linux.go#L155 The attached patch allows golang binaries to start under linux-user. The problem with doing that is that it doesn't actually change the behaviour. We use pthread_create to create the new thread, which glibc does with a clone with CLONE_SYSVSEM set. We can't tell the difference between "guest program needs the new threads to not share SysV semaphore behaviour" and "guest program doesn't care but didn't provide the flag" so we err on the side of caution and refuse to create a thread that doesn't behave the way the guest asked us for it to behave. True, but it used to work albeit with slightly wrong semantics. It now fails hard even though the golang runtime doesn't make any use of Sys V semaphores so the presence of the flag is not noticeable by any normal user. You can also apply this patch to go - I don't have an opinion on the correct course of action though! diff --git a/src/runtime/os_linux.go b/src/runtime/os_linux.go index a6efc0e3d1..64218e3f7e 100644 --- a/src/runtime/os_linux.go +++ b/src/runtime/os_linux.go @@ -132,7 +132,8 @@ const ( _CLONE_FS | /* share cwd, etc */ _CLONE_FILES | /* share fd table */ _CLONE_SIGHAND | /* share sig handler table */ - _CLONE_THREAD /* revisit - okay for now */ + _CLONE_THREAD | /* revisit - okay for now */ + _CLONE_SYSVSEM ) //go:noescape Note that there is a go bug about this issue too: https://github.com/golang/go/issues/20763 The go team have applied the above patch and I can confirm that it is now working properly using go-tip. This means it will be fixed in go 1.10. So if you recompile your go binary with go-tip or go 1.10 when it is released, it will run fine under qemu-system-arm. Since this has been fixed/worked around on the go side (thanks for following up with that!) I'm going to close this as "wontfix" on QEMU's side. It would be nice to support clone() with non-standard flags but since we can't do that while we still link with libc there's no way we can do this without a massive (and massively painful!) redesign to remove our libc dependency so that all of QEMU's linux-user code runs bare on the kernel. I just gave it a test with qemu-arm and Go binaries still crash for me, albeit differently: root@nofan:/# cat hello.go package main import "fmt" func main() { fmt.Println("hello world") } root@nofan:/# gccgo-7 hello.go -o hello root@nofan:/# ./hello mmap errno 9 fatal error: mmap runtime stack: mmap errno 9 fatal error: mmap panic during panic runtime stack: mmap errno 9 fatal error: mmap stack trace unavailable root@nofan:/# Should I file a new bug report? Yes, new bug please, that's definitely a different symptom and likely an unrelated issue.