golang binaries fail to start under linux-user

Bug #1696353 reported by Will Newton
10
This bug affects 2 people
Affects Status Importance Assigned to Milestone
QEMU
Won't Fix
Undecided
Unassigned

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
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.

Revision history for this message
Will Newton (will-newton) wrote :
Revision history for this message
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.

Revision history for this message
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.

Revision history for this message
Nick Craig-Wood (nick-craig-wood) wrote :

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

Revision history for this message
Nick Craig-Wood (nick-craig-wood) wrote :

Note that there is a go bug about this issue too: https://github.com/golang/go/issues/20763

Revision history for this message
Nick Craig-Wood (nick-craig-wood) wrote :

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.

Revision history for this message
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
Revision history for this message
John Paul Adrian Glaubitz (glaubitz) wrote :

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?

Revision history for this message
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  
Everyone can see this information.

Other bug subscribers

Remote bug watches

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