golang binaries fail to start under linux-user

Bug #1696353 reported by Will Newton on 2017-06-07
This bug affects 2 people
Affects Status Importance Assigned to Milestone

Bug Description

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
 /usr/lib/golang/src/runtime/proc.go:126 +0x24
 /usr/lib/golang/src/runtime/asm_arm.s:247 +0x80

goroutine 1 [running]:
 /usr/lib/golang/src/runtime/asm_arm.s:192 +0x4 fp=0x109287ac sp=0x109287a8
 /usr/lib/golang/src/runtime/proc.go:127 +0x5c fp=0x109287d4 sp=0x109287ac
 /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:


The attached patch allows golang binaries to start under linux-user.

Peter Maydell (pmaydell) wrote :

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.

Will Newton (will-newton) wrote :

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 */


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.

Peter Maydell (pmaydell) wrote :

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.

Changed in qemu:
status: New → Won't Fix

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

Should I file a new bug report?

Peter Maydell (pmaydell) wrote :

Yes, new bug please, that's definitely a different symptom and likely an unrelated issue.

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.